登录 |  注册
首页 >  服务器/安全 >  Tomcat容器 从入门到精通学习笔记 >  YoungGC频繁和时间过长分析与解决

YoungGC频繁和时间过长分析与解决

gc.png

总结下工作中遇到的GC问题。

一、JVM参数设置不当

机器4G,部分JVM参数设置

-Xmx3296m -Xms3296m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxGCPauseMillis=200 -XX:+UseG1GC 
-XX:-OmitStackTraceInFastThrow -XX:MinHeapFreeRatio=30 -XX:MaxHeapFreeRatio=50

现象:young GC比较频繁,并且不稳定,每1、2个小时会出现YGC次数激增,偶尔伴随Full GC,此时CPU状态也上升到100%。

查看日志:

日志情况.jpg

分析原因:G1 GC动态调整新生代大小(默认5%-60%),从日志看出调整后的Eden区太小,导致很容易发生young gc。

解决方案:

调整JVM参数,将新生代下限从5%调整到35%:

-XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=35 -XX:G1MaxNewSizePercent=60

补充:Google时,看到说因为G1需要Mixed GC,Mixed GC会扫描Eden,Survivor,和1/8(默认)Old。因为比Young GC多扫描Old区,所以为了尽力实现最大停顿时间,在Mixed GC前的Young GC急剧缩小了Eden Heap的大小,所以调大最大停顿时间也能缓解此问题。

结果:YGC次数更平稳,FGC未出现

二、代码不合理

现象:每3小时出现一次YGC时间超过超过300ms,此时CPU和网络状态正常,只有内存增加。

当时排障的日志没截图保存下来,简单说一下主要耗时就是Object Copy占了大量时间,如图红色框部分

copy时间较长.jpg

分析:通过代码发现每3个小时会全量拉一批某表的信息做本地缓存。Object Copy占了大量时间,说明需要Copy的对象很多。因为是缓存对象,所以不能回收。

解决方案:使用增量刷新的方式。伪代码:

int total = getTotalCount();
int pageSize = 500;
int(int i = 0 , i < total, i += pageSize){
  List list = exec("select * from my_table limit ?,?", i ,pageSize)
  CACHE.putAll(list);
}

采用这种方法需要注意的点:

1.可能导致刷新的数据不全,在刷新缓存时如果有新数据插入,则可能导致部分的缓存没有刷新。该问题的优化方式之一是:更新完缓存后看缓存的size是否等于表中数据的条数,如果不等于,说明刷新缓存过程中出现了变动,可以重新更新缓存(CAS思想)。

2.这种改进方法降低了吞吐量,一般来说这种定时任务都是以吞吐量为优先,改进这个问题是因为该问题影响了我系统的其他实时性功能,所以需不需要改进还是根据自己系统的需求。

原文链接: https://www.yukx.com/javadev/article/details/2351.html 优科学习网YoungGC频繁和时间过长分析与解决

<<上一课程
推荐文章
  • 总结下工作中遇到的GC问题。一、JVM参数设置不当机器4G,部分JVM参数设置-Xmx3296m -Xms3296m -Xss256k -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxGCPauseMillis=200 -XX:+Use
  • 1.  /:根目录,一般根目录下只存放目录,在终端里输入/home,其实是在告诉电脑,先从/(即根目录)开始,再进入到home目录;2.  /bin,/user/bin:可执行的二进制文件的目录,如常用的命令:ls,tar,mv,cat等;3.  /boot:放置Linux系统启动时用到的一些文件,
  • 一、CentOS简介:Centos是社区企业操作系统,是Linux发行版之一。centos是由RedHatEnterpriseLinux依照开放源代码规定释出的源代码所编译而成,但它并不包含封闭源代码软件。You have specified that the package 'gcc' should be installed.
  • 1、首先,打开VM虚拟,在顶部点击虚拟机的选项卡,再在往下弹出的菜单中点击安装vmwaretools。2、然后,在虚拟机系统中弹出的自动播放的窗口中点击运行setup64.exe。3、接着,在进入到的欢迎界面的窗口中点击底部的下一步按钮。4、之后,根据界面的跳转和提示,再点击底部的安装按钮。5、如图
  • netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。如果你的计算机有时候接收到的数据报导致出错数据或故障,你不必感到奇怪,
  • jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 注意!!!:使用的jdk版本是jdk8.类加载统计:Loaded:加载class的数量Bytes:所占用空间大小Unloaded:未加载数量By
学习大纲