我的 Java 应用程序的堆大小
不断增长,直到达到最大堆大小
1G
。为什么会这样?
我使用这些参数启动我的应用程序:
java -Xmx1G -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahUncommitDelay=5000 -XX:ShenandoahGuaranteedGCInterval=10000 -Dlog4j.configurationFile=./log4j2.xml -jar applicaiton.jar
编辑: 当我重新启动应用程序时,您会看到“堆大小”和“已用堆”之间没有差距,但这个差距越来越大,我可以以某种方式限制该差距吗?
最佳答案
我不太熟悉新 Shenandoah GC 的正常运行方式。然而,该图表(对我来说)并没有什么特别令人担忧的地方。
根据https://shipilev.net/talks/devoxx-Nov2017-shenandoah.pdf ,此 GC 在内存利用率方面的操作方式 (MO) 与其他一些收集器有点不同。
"We shall take all the memory when we need it, but we shall also give it back when we don’t".
如果分配器上有很大的负载(即分配了很多对象),Shenandoah 将积极扩展堆。这是基于这样的观察:如果有足够的工作空间,低暂停 GC 是最高效的(并且最有可能跟上!)。
但另一方面,如果您的系统空闲,GC 会比许多其他 GC 更自由地将内存返还给操作系统。
这似乎符合您问题中的内存图。
另一件事需要注意的是堆大小(橙色)远未接近最大堆限制。如果接近该限制,GC 将停止增长堆。
最后,请注意,您显然可以通过使用较小的 -XX:ShenandoahUncommitDelay=<millis>
值来鼓励 Shenandoah 更快地归还未提交的内存。选项。但是,建议不要将其设置得太小,因为这可能会减慢分配器的速度。
(来源:https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html)
关于java - "Heap size"的增长速度比 "Used heap"快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56109118/