Hotspot JVM - G1GC 堆大小调整问题

问题描述 投票:0回答:1

我最近正在测试一个并发负载相对较高的演示应用程序。该应用程序是一个 java 应用程序,在 Hotspot JVM (1.8.0_111) 上运行。

使用 4G 堆和并行吞吐量收集器,我可以获得约 400 TPS 的最大吞吐量。吞吐量图表(作为负载的函数)如下所示。

因为 Oracle 建议对大于 4G 的堆大小使用 G1GC,所以我想尝试 G1,看看这是否对我的应用程序吞吐量有任何好处。

令我惊讶的是,通过 G1GC,我看到了以下吞吐量趋势。

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

我看到最初,在 4G 堆中,1.5G 分配给旧代区域,2.5G 分配给伊甸园区域。但随着时间的推移,旧一代不再适合 1.5G,堆的大小会被调整。这看起来无伤大雅。但问题似乎出在调整大小的方式上。

所有 4G 现在都分配给老一代区域,几乎没有分配给伊甸园区域。现在,当需要将某些内容分配给伊甸园时,堆会再次调整大小。这成为新的常态,堆的大小被反复调整,导致应用程序产生巨大的性能成本。

有人在 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 日志
java jvm heap-memory jvm-hotspot g1gc
1个回答
1
投票

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

  • [GC暂停(G1巨大分配)(年轻)(初始标记)
  • 【GC暂停(G1 Evacuation Pause)(年轻)(到空间耗尽)

巨大的分配需要老一代的空间,空间耗尽会增加年轻一代的规模。他们基本上是在互相竞争。

看起来您分配大量巨大对象(> 1/2 G1 区域大小)的速度比 IHOP 启动的并发周期收集它们的速度更快。

您可以尝试增加区域大小。如果它们是大型原始数组(即不是引用数组),那么实验性的“渴望回收功能”也可能会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.