首页 > 其他分享 >(转)关于施用full gc频繁的分析及解决

(转)关于施用full gc频繁的分析及解决

时间:2023-07-31 10:36:17浏览次数:39  
标签:full old young concurrent gc CMS 施用

分析

当频繁full gc时,jstack打印出堆栈信息如下:

sudo -u admin -H /opt/taobao/java/bin/jstack `pgrep java` > #your file path#

可以看到的确是在跑低价信息

另外在应用频繁full gc时和应用正常时,也执行了如下2种命令:

sudo -u admin -H /opt/taobao/java/bin/jmap -histo `pgrep` > #your file path#

sudo -u admin -H /opt/taobao/java/bin/jmap -histo:live `pgrep` > #your file path#(live会产生full gc)

目的是确认以下2种信息:

(1)是否存在某些引用的不正常,造成对象始终可达而无法回收(Java中的内存泄漏)

(2)是否真是由于在频繁full gc时同时又有大量请求进入分配内存从而处理不过来,

       造成concurrent mode failure?

下图是在应用正常情况下,jmap不加live,产生的histo信息:

下图是在应用正常情况下,jmap加live,产生的histo信息:

下图是在应用频繁full gc情况下,jmap不加live和加live,产生的histo信息:

从上述几个图中可以看到:

(1)在应用正常情况下,图中标红的对象是被回收的,因此不是内存泄漏问题

(2)在应用频繁full gc时,标红的对象即使加live也是未被回收的,因上就是在频繁full gc时,

       同时又有大量请求进入分配内存从而处理不过来的问题

先从解决问题的角度,看怎样造成频繁的full gc?

从分析CMS GC开始

先给个CMS GC的概况:

(1)young gc

可以看到,当eden满时,young gc使用的是ParNew收集器

ParNew: 2230361K->129028K(2403008K), 0.2363650 secs解释:

1)2230361K->129028K,指回收前后eden+s1(或s2)大小

2)2403008K,指可用的young代的大小,即eden+s1(或s2)

3)0.2363650 secs,指消耗时间

2324774K->223451K(3975872K), 0.2366810 sec解释:

1)2335109K->140198K,指整个堆大小的变化

(heap=(young+old)+perm;young=eden+s1+s2;s1=s2=young/(survivor ratio+2))

2)0.2366810 sec,指消耗时间

[Times: user=0.60 sys=0.02, real=0.24 secs]解释:指用户时间,系统时间,真实时间

(2)cms gc

当使用CMS收集器时,当开始进行收集时,old代的收集过程如下所示:

a)首先jvm根据-XX:CMSInitiatingOccupancyFraction,-XX:+UseCMSInitiatingOccupancyOnly

    来决定什么时间开始垃圾收集

b)如果设置了-XX:+UseCMSInitiatingOccupancyOnly,那么只有当old代占用确实达到了

    -XX:CMSInitiatingOccupancyFraction参数所设定的比例时才会触发cms gc

c)如果没有设置-XX:+UseCMSInitiatingOccupancyOnly,那么系统会根据统计数据自行决定什么时候

   触发cms gc;因此有时会遇到设置了80%比例才cms gc,但是50%时就已经触发了,就是因为这个参数

   没有设置的原因

d)当cms gc开始时,首先的阶段是CMS-initial-mark,此阶段是初始标记阶段,是stop the world阶段,

    因此此阶段标记的对象只是从root集最直接可达的对象

CMS-initial-mark:961330K(1572864K),指标记时,old代的已用空间和总空间

e)下一个阶段是CMS-concurrent-mark,此阶段是和应用线程并发执行的,所谓并发收集器指的就是这个,

    主要作用是标记可达的对象

此阶段会打印2条日志:CMS-concurrent-mark-start,CMS-concurrent-mark

f)下一个阶段是CMS-concurrent-preclean,此阶段主要是进行一些预清理,因为标记和应用线程是并发执行的,

   因此会有些对象的状态在标记后会改变,此阶段正是解决这个问题

因为之后的Rescan阶段也会stop the world,为了使暂停的时间尽可能的小,也需要preclean阶段先做一部分

   工作以节省时间

此阶段会打印2条日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean

g)下一阶段是CMS-concurrent-abortable-preclean阶段,加入此阶段的目的是使cms gc更加可控一些,

    作用也是执行一些预清理,以减少Rescan阶段造成应用暂停的时间

此阶段涉及几个参数:

-XX:CMSMaxAbortablePrecleanTime:当abortable-preclean阶段执行达到这个时间时才会结束

-XX:CMSScheduleRemarkEdenSizeThreshold(默认2m):控制abortable-preclean阶段什么时候开始执行,

即当eden使用达到此值时,才会开始abortable-preclean阶段

-XX:CMSScheduleRemarkEdenPenetratio(默认50%):控制abortable-preclean阶段什么时候结束执行

此阶段会打印一些日志如下:

CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,

CMS:abort preclean due to time XXX

h)再下一个阶段是第二个stop the world阶段了,即Rescan阶段,此阶段暂停应用线程,对对象进行重新扫描并

    标记

YG occupancy:964861K(2403008K),指执行时young代的情况

CMS remark:961330K(1572864K),指执行时old代的情况

此外,还打印出了弱引用处理、类卸载等过程的耗时

i)再下一个阶段是CMS-concurrent-sweep,进行并发的垃圾清理

j)最后是CMS-concurrent-reset,为下一次cms gc重置相关数据结构

(3)full gc:

有2种情况会触发full gc,在full gc时,整个应用会暂停

a)concurrent-mode-failure:当cms gc正进行时,此时有新的对象要进行old代,但是old代空间不足造成的

b)promotion-failed:当进行young gc时,有部分young代对象仍然可用,但是S1或S2放不下,

   因此需要放到old代,但此时old代空间无法容纳此

 


频繁full gc的原因

从日志中可以看出有大量的concurrent-mode-failure,因此正是当cms gc进行时,有新的对象要进行old代,

但是old代空间不足造成的full gc

进程的jvm参数如下所示:

影响cms gc时长及触发的参数是以下2个:

-XX:CMSMaxAbortablePrecleanTime=5000

-XX:CMSInitiatingOccupancyFraction=80

解决也是针对这两个参数来的

根本的原因是每次请求消耗的内存量过大

解决

(1)针对cms gc的触发阶段,调整-XX:CMSInitiatingOccupancyFraction=50,提早触发cms gc,就可以

       缓解当old代达到80%,cms gc处理不完,从而造成concurrent mode failure引发full gc

(2)修改-XX:CMSMaxAbortablePrecleanTime=500,缩小CMS-concurrent-abortable-preclean阶段

       的时间

(3)考虑到cms gc时不会进行compact,因此加入-XX:+UseCMSCompactAtFullCollection

      (cms gc后会进行内存的compact)和-XX:CMSFullGCsBeforeCompaction=4

      (在full gc4次后会进行compact)参数

但是运行了一段时间后,只不过时间更长了,又会出现频繁full gc

计算了一下heap各个代的大小(可以用jmap -heap查看):

total heap=young+old=4096m

perm:256m

young=s1+s2+eden=2560m

young avail=eden+s1=2133.375+213.3125=2346.6875m

s1=2560/(10+1+1)=213.3125m

s2=s1

eden=2133.375m

old=1536m

可以看到eden大于old,在极端情况下(young区的所有对象全都要进入到old时,就会触发full gc),

因此在应用频繁full gc时,很有可能old代是不够用的,因此想到将old代加大,young代减小

改成以下:

-Xmn1920m

新的各代大小:

total heap=young+old=4096m

perm:256m

young=s1+s2+eden=1920m

young avail=eden+s1=2133.375+213.3125=1760m

s1=1760/(10+1+1)=160m

s2=s1

eden=1600m

old=2176m

此时的eden小于old,可以缓解一些问题

 


标签:full,old,young,concurrent,gc,CMS,施用
From: https://blog.51cto.com/u_2650279/6905820

相关文章

  • AGC049F 更优秀的做法
    题面给定长度为\(n\)的整数序列\(A\),\(B\)和\(C\)。snuke是开心的,当且仅当下面的条件满足:对于任意整数\(x\),均有\(\sum_{1\lei\len}|A_i-x|\le\sum_{1\lei\len}|B_i-x|\)。他决定改变\(A\)中的一些元素来变得开心。把\(A_i\)改成\(t\)需要花费......
  • hdu7319 String and GCD
    StringandGCD首先我们需要用kmp的fail建树,然后需要利用到欧拉反演。\[n=\sum_{d|n}\varphi(d)\]对于这题来说\[(i,j)=\sum_{d|(i,j)}\varphi(d)=\sum_{d|i,d|j}\varphi(d)\]那么我们只需要用一个桶存每个约数从根到当前节点出现了多少次。然后枚举约数也有一个技巧,具体......
  • Mac部署AIGC图片生成服务——基于stable-diffusion
    Mac部署AIGC图片生成服务——基于stable-diffusionAIGC即人工智能内容生成,是目前非常火的一个概念。随着各种大模型的问世,通过AI来生成内容的能已经越来越强大。本文将从应用实践方面进行介绍如何在自己的PC电脑上部署一个强大的AI图片生成服务。关于AI绘图,我相信你一定不太陌生,......
  • 国产MCU-CW32F030开发学习-圆形GC9A01_LCD模块
    国产MCU-CW32F030开发学习-圆形GC9A01_LCD模块硬件平台CW32_48F大学计划板CW32_IOT_EVA物联网开发评估套件1.28寸圆形彩色TFT显示屏高清IPS模块240X240SPI接口GC9A01产品介绍1.28寸圆形IPS彩屏,支持RGB65K色显示,显示色彩丰富240X240分辨率,显示清晰IPS全视角面板,超......
  • 使用WGCLOUD监测安卓(Android)设备的运行状态
    WGCLOUD是一款开源运维软件,除了能监测各种服务器、主机、进程应用、端口、接口、docker容器、日志、数据等资源WGCLOUD还可以监测安卓设备,比如安卓手机、安卓设备等我们只要下载对应的安卓客户端,部署运行即可详细说明:https://www.wgstart.com/help/docs63.html......
  • JDK17和ZGC学习
    ZGCSTW会延长服务的RT。CMS有碎片化问题。G1只能在STW的时候移动对象。他俩STW时间随着活跃对象的增加而增加。内存几十GB有可能有几十几百秒的STW。甚至FullGC情况。JDK11引用了ZGC。 ZGC是一款几乎没有STW且支持大堆的GC。STW时间不超过10msSTW时间不随活跃对象的......
  • 【模板】数论基础:exGCD,exCRT,inverse,Lucas,BSGS,primitive root
    7.29数论WIP\(a\equivb\pmodp\Rightarrow\frac{a}{d}\equiv\frac{b}{d}\pmod{\frac{p}{d}},d=\gcd(a,b,p)\)。exGCD若\((a,b)=1\),则\(0\leqx<b\),\(ax\bmodb\)互不相同,有一个是\(1\)。证明:\(ax_1\equivax_2\pmodb\)则\((x_1-x_2)a|b\),因为......
  • AIGC与NLP大模型实战-经典CV与NLP大模型及其下游应用任务实现
    点击下载:AIGC与NLP大模型实战-经典CV与NLP大模型及其下游应用任务实现提取码:hqq8当今社会是科技的社会,是算力快速发展的时代。随着数据中心、东数西算、高性能计算、数据分析、数据挖掘的快速发展,大模型得到了快速地发展。大模型是“大算力+强算法”相结合的产物,是人工智能的发展......
  • gcc的编译过程
    一、gcc的编译过程、源文件xxx.c预处理文件xxx.i汇编文件xxx.s未链接的二进制文件xxx.o通过连接,产生最终可执行的二进制文件二、编译步骤的工作1、预处理头文件被包含进来(复制):#include宏定义会被替换:#define取消宏定义:#undef条件编译:#if#ifde......
  • AT_agc022_a 题解
    洛谷链接&Atcoder链接本篇题解为此题较简单做法及较少码量,并且码风优良,请放心阅读。题目简述给定字符串\(S\),仅包含互不相同的小写字母,你需要找到仅包含互不相同的小写字母的字符串中,第一个字典序比它大的字符串,如果找不到输出\(-1\)。(\(|S|\le26\))思路这篇题解......