未完全使用的 Java 堆大小

2022-09-03 07:17:25

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

我强调-Xmx128m的内存使用。

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

enter image description here

为什么剩下的20米没有使用?


答案 1

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

垃圾回收的昂贵部分是查找和处理不是垃圾的对象。

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

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

您可以通过 JVM 选项更改 GC 阈值、生成大小等,但最好不要这样做。一个更好的主意是弄清楚为什么应用程序的内存使用量不断上升。最有可能出现内存泄漏...即一个错误...在导致此问题的代码中。花费精力查找并修复这些错误,而不是担心为什么不使用所有内存。

(实际上,您正在使用它...但不是所有的时间。


答案 2

堆被分成年轻一代(伊甸园空间,以及两个大小相同的幸存者空间,通常称为从和到),老一代(终身)和永久空间。

该选项设置堆大小。因此,区域(具有默认大小)实际上是永久空间 - 也许,我们不知道有关您的压力测试的详细信息,实际上没有对象从伊甸园移动到永久或永久,因此当伊甸园耗尽空间时,这些区域保持空白。Xmx/Xms


推荐