我目前正在使用 Visual VM 监控正在运行的 Java 应用程序:http://visualvm.java.net/
我通过 -Xmx128m 来强调内存使用情况。
运行时,我看到堆大小增加到 128m(如预期的那样),但是在遇到 java 堆空间错误之前,使用的堆收敛到大约 105m。
为什么这些剩下的 20m 没有使用?
最佳答案
您需要了解有关垃圾收集器人体工程学的一个核心事实:
The costly part of garbage collection is finding and dealing with the objects that are NOT garbage.
这意味着:随着堆接近其最大容量,GC 将花费越来越多的时间来回收越来越少的空间。如果 GC 尝试使用内存的最后一个字节,最终结果将是您的 JVM 将花费越来越多的时间进行垃圾收集,直到……最终……几乎没有任何有用的工作被完成。
为了避免这种病态的情况,JVM 监控用于 GC 和做有用工作的时间比例。当比率超过可配置的阈值时,GC 会引发 OutOfMemoryError
...即使(技术上)有可用内存可用。这可能就是您所看到的,尽管其他解释同样合理。
您可以通过 JVM 选项更改 GC 阈值、生成大小等,但最好不要这样做。一个更好的主意是弄清楚为什么您的应用程序的内存使用量不断上升。很可能存在内存泄漏......即错误......在您的代码中导致这种情况。把精力花在寻找和修复这些错误上,而不是担心为什么没有使用所有内存。
(事实上,您正在使用它……但并非一直如此。)
关于Java 堆大小未完全使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5882216/