高峰请求到来时频繁且长时间的Java GC,导致应用停止响应10分钟

我有一个提供在线视频播放服务的 Java 应用程序。当高峰流量到来时(比如用户点击手机推送窗口),GC开销很大,我在GC日志中可以看到“提升失败”和“并发模式失败”的信息,GC很及时消耗,几乎需要10分钟才能完成一个GC周期,这使得应用程序长时间无法响应。


我知道问题应该是内存使用的错误代码设计,任何人都可以帮助弄清楚如何解决 GC 问题吗?谢谢。


这是我的服务器环境:


cat /etc/redhat-release

CentOS release 6.8 (Final)


free -h

             total       used       free     shared    buffers     cached

Mem:           31G        31G       302M        16K       260M       6.5G

-/+ buffers/cache:        24G       7.1G

Swap:         2.0G       564M       1.4G


java -version

java version "1.7.0_131"

OpenJDK Runtime Environment (rhel-2.6.9.0.el6_8-x86_64 u131-b00)

OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)

这是我原来的 JVM 设置:


55634 XmlConfiguration -Xmx22528m -Xms22528m -verbose:gc -XX:NewRatio=3

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled

-Xloggc:/data/logs/jetty/gc.log -XX:GCLogFileSize=10M -XX:NumberOfGCLogFiles=10

-XX:+UseGCLogFileRotation -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps

-XX:+PrintGCDetails -XX:+DisableExplicitGC -XX:+ScavengeBeforeFullGC

-XX:+CMSScavengeBeforeRemark -XX:+UseCMSInitiatingOccupancyOnly

-XX:CMSInitiatingOccupancyFraction=70

-Djetty.home=/usr/local/jetty-distribution-8.1.16.v20140903

我尝试了一些解决方案,但问题仍然存在。


1) 调整JVM参数:-XX:CMSInitiatingOccupancyFraction=50,使CMS GC更早,为应用程序线程提供更多空闲内存。


2)调整JVM参数:-XX:NewRatio=2,让新生代变大。


3)调整JVM参数:-XX:PermSize=512m,-XX:MaxPermSize=512m,使持久化生成更大。


4) 对单台服务器设置限速器,可以保护下划线应用。


胡说叔叔
浏览 153回答 2
2回答

30秒到达战场

查看您的 GC 日志,CMS 似乎不是您应用的正确选择。考虑尝试其他 GC 算法:并行 GC(它会给你 10-30 秒的定期暂停,但不是 10 分钟)如果你可以升级到 Java 8,G1 可能是一个选项(它可能很好也可能很坏——看你的运气了)如果您想坚持使用 CMS ......我可以在GC日志中看到有关“提升失败”和“并发模式失败”的信息,而且GC非常耗时,几乎需要10分钟才能完成一个GC周期...您的提升率非常高(100+ MiB/s)2019-08-17T11:07:38.895+0800: 48789.385: [GC2019-08-17T11:07:38.895+0800: 48789.385: [ParNew: 5098592K->576704K(5190464K), 0.2818390 secs] 16761372K->12241212K(22491968K), 0.2826330 secs] [Times: user=2.24 sys=0.00, real=0.28 secs]2019-08-17T11:07:46.308+0800: 48796.799: [GC2019-08-17T11:07:46.309+0800: 48796.799: [ParNew: 5190464K->576704K(5190464K), 0.4371320 secs] 16854972K->12504773K(22491968K), 0.4380620 secs] [Times: user=2.97 sys=0.01, real=0.44 secs]CMS 需要很大的旧空间大小来处理这样的吞吐量并保持低碎片。不过,您的服务器似乎已经达到内存限制。

一只萌萌小番薯

我终于弄清楚了根本原因。代码在高峰流量到来时会产生大量对象(超过10GB),导致young GC频繁发生,CMS GC回落到SerialOld GC,造成长时间STW。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java