我的程序中有很多线程,其中一个线程一直在请求内存而没有释放它。
如gc日志所示,我发现了连续的Full GC(人体工程学),但是该程序没有获得更多的内存,并且所有的线程都停止了,除了JVM垃圾回收线程。
我阅读了官方文档,GC Ergonomics尝试增大或缩小堆以实现特殊目标,例如最小化暂停时间和/或吞吐量。但是,在Full GC (Ergonomics)
之后,如gc日志所示,无论大小,堆的大小都没有改变。
我一直在徘徊,为什么全GC(人体工程学)后堆的大小没有改变
我的计算机有16G内存,没有交换空间。此计算机上没有其他应用程序运行
JVM Args:
-XX:+PrintGCDateStamps -Xloggc:gc.log -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.managementote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xmx10G -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails
gc日志:
gc log
答案 0 :(得分:0)
这里有几件事要看。
首先,描述应用程序的方式似乎是经典的内存泄漏(即使这是故意的)。如果您有一个线程不断分配对其维护引用的对象,则最终将耗尽堆空间。查看GC日志和堆图,这就是正在发生的事情。完整的GC正在连续运行,以尝试回收空间以保持应用程序运行。收集器没有回收任何空间,这实际上使我惊讶于VM不会因OutOfMemoryError而停止。如果堆连续达到98%或更多,并且GC无法回收超过2%的空间,则会导致OutOfMemoryError。 GC日志显示这是正确的。
下一个问题是为什么堆空间不会扩展到8Gb以上。您将-Xmx选项设置为10Gb,因此从逻辑上讲,您可以期望堆在需要时增长到该大小。在16Gb机器上,没有理由不发生这种情况。我将添加选项-Xms,还将初始大小也设置为10Gb,这将强制JVM在启动时保留所有这些空间。
正如评论中指出的那样,您应该对应用程序进行概要分析,以更好地了解要维护哪些对象的引用,以及是否有某种方法可以减少这种情况。使用无限制的数据集,您将始终达到无法继续应用程序的地步。