当内存实际可用时,Java内存不足错误

时间:2012-01-25 23:14:51

标签: java memory-management

我继续遇到OOM错误和随后的JBoss崩溃,即使堆显示分配给它的所有内存都没有用完。

例如:如果我将1200MB分配为堆大小(Xmx),则崩溃发生在远低于该限制的情况下,堆中的每个代(年轻/老/ perm)都不是100%。

这个盒子有足够的内存。为什么java会在内存不足时报告此错误?

 Heap

 PSYoungGen      total 67456K, used 9525K [0x57540000, 0x5c170000, 0x5fa90000)
  eden space 66432K, 12% used [0x57540000,0x57d91520,0x5b620000)
  from space 1024K, 98% used [0x5c070000,0x5c16c198,0x5c170000)
  to   space 3008K, 0% used [0x5bb90000,0x5bb90000,0x5be80000)

 PSOldGen        total 466048K, used 313530K [0x14a90000, 0x311b0000, 0x57540000)
  object space 466048K, 67% used [0x14a90000,0x27cbea38,0x311b0000)

 PSPermGen       total 226432K, used 141461K [0x04a90000, 0x127b0000, 0x14a90000)
  object space 226432K, 62% used [0x04a90000,0x0d4b55e8,0x127b0000)

2 个答案:

答案 0 :(得分:3)

是的,当你还有足够的可用堆空间时,可以获得一个OOME。

当您创建线程时,JVM需要为线程的堆栈分配内存。但是,JVM不会在堆中分配线程堆栈。 (线程堆栈需要在内存中,不会被垃圾收集器移动。)而是直接从操作系统请求它。如果操作系统无法满足该请求,则无论您的堆大小如何,都会得到OOME ....

显然,如果您的应用程序超出了操作系统的每进程线程限制,则在创建线程期间也会出现OOME。 (在Linux / Unix上,它由ulimit -u ...)

控制

说出你的情况发生了什么有点困难。我怀疑你的应用程序只是试图创建太多线程并遇到上述限制之一。您可以尝试减少线程堆栈大小,但更好的方法是弄清楚为什么要创建这么多线程并停止它。 (大量的线程往往浪费资源......并以各种方式使应用程序变慢。)

答案 1 :(得分:2)

看看JBoss社区网站上的this answer,了解为什么你会得到Unable来创建一个新的线程OOM