Java堆大小未完全使用

时间:2011-05-04 10:47:35

标签: java memory size heap visualvm

我正在使用Visual VM监视我正在运行的java应用程序:http://visualvm.java.net/

我用-Xmx128m强调内存使用情况。

运行时,我看到堆大小增加到128m(正如预期的那样),但是在遇到java堆空间错误之前,使用的堆收敛到大约105m。

enter image description here

为什么这些剩下20米,没用过?

3 个答案:

答案 0 :(得分:5)

您需要了解垃圾收集器人机工程学的核心事实:

  

垃圾收集的代价是寻找并处理非垃圾的对象。

这意味着:当堆接近其最大容量时,GC将花费越来越多的时间在回收空间中获得越来越少的回报。如果GC试图使用内存的每个最后一个字节,那么最终的结果就是你的JVM会花费越来越多的时间来收集垃圾,直到......最终......几乎没有任何有用的工作正在完成。

为了避免这种病态情况,JVM监视GC花费和执行有用工作的时间比率。当比率超过可配置的阈值时,GC会提升OutOfMemoryError ...即使(技术上)有可用的可用内存。这可能就是你所看到的,尽管其他解释同样合理。

您可以通过JVM选项更改GC阈值,生成大小等,但最好不要这样做。更好的想法是弄清楚为什么你的应用程序的内存使用量不断上升。最有可能是内存泄漏...即代码中的错误...导致此问题。花费你的努力来发现和修复这些错误,而不是担心为什么你没有使用所有的内存。

(事实上,你正在使用它......但不是所有的时间。)

答案 1 :(得分:4)

Java将其内存分成几代。如果终生代填充,则可能会出现堆空间错误。通常情况下,它们会动态调整大小,但如果您设置了固定大小,则不会。

答案 2 :(得分:4)

  

堆在Young-Generation(Eden-Space,两个相同大小的Survivor-Spaces,通常称为From和To),Old Generation(Tenured)和Permanent Space中分开。

Xmx/Xms选项设置整体堆大小。所以一个区域(默认大小)实际上是永久空间 - 也许,我们不知道你的压力测试的细节,没有任何物体实际上从伊甸园转移到终身或永久,所以这些区域仍然是空的,而伊甸园用完了太空了。