当前位置: 首页 > 知识库问答 >
问题:

热点JVM-G1GC堆大小调整问题

卫才哲
2023-03-14

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

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

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

令我惊讶的是,在G1GC中,我看到了低于吞吐量的趋势。

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

我看到最初,在4G堆中,1.5G分配给老世代地区,2.5G分配给伊甸园地区。但随着时间的推移,旧的gen不再适合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日志

共有1个答案

江阳冰
2023-03-14

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

  • [GC暂停(G1巨大分配)(年轻)(初始标记)
  • [GC暂停(G1疏散暂停)(年轻)(空间耗尽)

庞大的配置需要旧世代的空间,空间耗尽推动年轻世代的规模。他们基本上是在相互竞争。

看起来你分配了很多巨大的物体(

您可以尝试增加区域大小。如果它们是大型基本阵列(即不是参考阵列),那么实验性的渴望回收功能可能也会有所帮助。

 类似资料:
  • 由于GC,我的突变率下降了。我的年轻一代GC花费了很长时间 G1年轻一代GC在1804ms.G1伊甸园空间:771751936 - 在最后5000毫秒内丢弃了变异消息:814表示内部超时,0表示跨节点超时。平均内部丢弃延迟:2874毫秒,平均跨节点丢弃延迟:0毫秒 为了避免这种情况,我应该减少MaxGCPauseMillis选项Cassandra-env.sh. 我们的默认值是500毫秒(JVM_

  • 问题内容: 调整在管理面板中设置的图像大小时出现问题。 然后我尝试删除height: 100px似乎可以解决问题的属性,但是由于某种原因关闭了一张图像 问题答案: 如果您不希望图像拉伸,则应固定一个尺寸,而将另一个尺寸设为auto。(这将保留图像的长宽比) 请参阅下面的示例,其中width在height自动调整时保持不变: 请参阅下面的示例,其中height在width自动调整时保持不变:

  • 问题内容: 我打算制作一个ContentPanel为600x600的JFrame,并且我希望JFrame的大小不可调整。在此框内,我绘制了一个600x600的红色轮廓矩形,以确保运行程序时所有内容都匹配。在限制JFrame的大小之前,我通过执行以下操作来设置JFrame的大小: 当我启动程序时,矩形的边界与JFrame的尺寸完全吻合。但是,当我在公式中添加isResizable(false)时,在

  • 我打算制作一个具有600x600的ContentPanel的JFrame,并且我希望JFrame不是可重放的。在这个框中,我画了一个600x600的红色矩形,以确保运行程序时所有内容都匹配。在限制JFrame的大小之前,我通过执行以下操作来设置JFrame的大小: 注意:在不修改大小的情况下创建一个JFrame也可以观察到这个异常。如果不使其不可调整大小,则没有可观察的Panel/ContentP

  • 有很多关于堆大小的帖子和站点,但是没有一个提到在调用JVM时如何找出我可以保留的最大可能堆大小。 任务是用最大可用堆大小xmx=max动态启动我的jvm(这里不需要讨论这个任务的对象!)。 我们可以考虑读取当前可用或空闲的内存,并将该大小用于xms和XMX。但这不起作用。 调用Java程序时: Java-XMS1536M-XMX1536M myApp 导致: 选择您选中的应用程序大约需要的堆。并在

  • 我想有一个StackPane作为根节点,它使叠加效果变得容易。 但是通过使用stackpane作为根,内部控件可以移出窗口。在下面的示例中,如果您将窗口缩小到足够小,您可以看到控件移出窗口,例如菜单栏和列表视图都移到左侧。我想防止这种情况,我该怎么做? 更新: 为StackPane内部的BorderPane设置对齐方式似乎有所帮助: