热点JVM -G1 GC堆大小调整问题

jtw3ybtb  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(210)

我最近测试了一个并发负载相对较高的演示应用程序,该应用程序是一个java应用程序,运行在Hotspot JVM(1.8.0_111)上。
使用4G堆和并行吞吐量收集器,我可以获得大约400 TPS的最大吞吐量。

因为Oracle建议对大于4G的堆使用G1GC,所以我想尝试G1,看看这是否对我的应用程序吞吐量有任何好处。
令我惊讶的是,在G1GC中,我看到了吞吐量趋势。

我真的很惊讶,决定深入研究一下,看看这里发生了什么。

我看到最初,在4G的堆中,1.5G被分配给了old gen区域,2.5G被分配给了eden区域。但是随着时间的推移,old gen不再适合1.5G,堆被调整了大小。这看起来是无害的。但是问题似乎在于调整大小的方式。
现在所有的4G都被分配给了旧的gen区域,几乎没有一个被分配给eden区域。现在,当有东西需要被分配给eden时,heap会再次调整大小。这成为了新的常态,heap会反复调整大小,从而导致应用程序的巨大性能开销。
有没有人注意到这一点之前与G1GC?有什么建议,以协商这个问题?
下面是带有JVM选项的启动命令行。

java -server -Xms4096m -Xmx4096m -XX:MetaspaceSize=100m -XX:MaxMetaspaceSize=100m -XX:MaxDirectMemorySize=512m -XX:MinMetaspaceFreeRatio=0 -XX:MaxMetaspaceFreeRatio=100 -XX:CompressedClassSpaceSize=20m -XX:InitialCodeCacheSize=50m -XX:ReservedCodeCacheSize=50m -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/tmp -Xloggc:/servers/logs/gc.log.2017-01-05-085234 -Djava.awt.headless=true -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -Dio.netty.leakDetectionLevel=simple -XX:MaxDirectMemorySize=512m -Dadmin.connectors.http.port=9000 -Dproxy.connectors.http.port=8080 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8654 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -server -cp ...

JVM选项:

-server 
-Xms4096m 
-Xmx4096m 
-XX:MetaspaceSize=100m 
-XX:MaxMetaspaceSize=100m 
-XX:MaxDirectMemorySize=512m 
-XX:MinMetaspaceFreeRatio=0 
-XX:MaxMetaspaceFreeRatio=100 
-XX:CompressedClassSpaceSize=20m 
-XX:InitialCodeCacheSize=50m 
-XX:ReservedCodeCacheSize=50m 
-XX:+AlwaysPreTouch 
-XX:+DisableExplicitGC 
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/var/tmp 
-Xloggc:/servers/logs/gc.log.2017-01-05-085234 
-Djava.awt.headless=true 
-XX:+UnlockCommercialFeatures 
-XX:+FlightRecorder 
-Dio.netty.leakDetectionLevel=simple 
-XX:MaxDirectMemorySize=512m 
-Dadmin.connectors.http.port=9000 
-Dproxy.connectors.http.port=8080 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8654 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-server 
-cp ...

请查找gc日志here

unftdfkk

unftdfkk1#

以下两种GC原因似乎有很多:

  • [GC暂停(G1巨大分配)(年轻)(首字母-标记)
  • [GC暂停(G1抽空暂停)(年轻)(至空间耗尽)

巨大的分配需要老一代的空间,对空间的消耗推动了年轻一代的规模。他们基本上是在相互竞争。
看起来你分配了很多巨大的对象(〉1/2 G1区域大小),速度比IHOP启动的并发周期收集它们的速度还快。
你可以试着增加区域的大小。如果它们是大的原始数组(即不是引用arrasy),那么实验性的eager reclaim feature也会有帮助。

相关问题