概述

本周有个同事过来咨询一个比较诡异的gc问题,大概现象是,系统一直在做cms gc,但是老生代一直不降下去,但是执行一次jmap -histo:live之后,也就是主动触发一次full gc之后,通过jstat -gcutil来看老生代一下就降下去了,初看下理论上不太可能,因为full gc也会对old做回收,于是我要同事针对他们的场景写了一个简单的demo出来,然后果然还真能重现,不过他的demo设置的Heap有32G,于是我通过慢慢调整,最终在很小的内存下也能重现出来

Demo

测试代码如下:

正如我上面注释里写的JVM参数,控制新生代200M,老生代300M,老生代使用率达到90%的时候触发CMS GC,大家可以跑跑看,这种情况下会发现不断做CMS GC,但是老生代就是不降下去,但是只要你主动触发一次Full GC,老生代立马就会回收。
当allocateMemory方法执行完之后,期待的结果是gc之后List及里面的byte数组都应该被回收掉,可是事实并不是这样的

初步定位

这段代码非常简单,我翻来覆去地看着这段代码,试图想改变点什么,能让问题出现峰回路转,我不断地控制for循环的次数和每次分配的内存大小,最终我将目标转移到那个ArrayList上,List里有个数组,在add过程中如果发现数组不够了,于是会进行扩容,那扩容就是创建新的数组,将老的对象放到新数组里,那我试想要是不做扩容会不会有问题?于是我开始调整ArrayList的初始化大小,当我调到一定大小,保证在add过程中不会做扩容,问题真出现了反转,居然能正常回收了,比如上面的demo,将数组长度设置为len,那结果就完全不一样了,老生代很快就被回收了
那目标能锁定到数组扩容了

数组扩容

ArrayList里的数组扩容,使用的是System.arrayCopy调用,这是一个native方法,在java层面创建一个新的长度的数组,然后将老数组和新数组都传进去,在native里将老数组里的元素指针拷贝到新数组里,其实做的是浅拷贝,反复看native这块实现,也基本解释不通那个现象,一度怀疑我对GC的理解了,是不是有哪些细节没有注意到。
经过我内存dump分析,发现上面Demo里的List对象确实被回收了,但是List里的数组没有被回收,这个数组里的byte数组都没有被回收

原来是这个鬼

带着百思不得其解的疑惑和我们组同事讨论,看看还有没有其他可能的没考虑到疑惑点,开始也都觉得疑惑,后来传胜突然想到会不会是存在跨代引用的问题,于是回过来仔细再想想每个步骤,好像还真有可能,因为传给System.arrayCopy的新数组是在java层面构建传进来的,在新生代分配的可能性最大,这样再加上拷贝仅仅是浅拷贝,那么老生代里的byte数组因为存在新生代里新数组的引用,那仅仅做CMS GC就不可能回收这些老生代的对象了,因为CMS GC的一个gc root就是新生代里的对象

那何解

至此终于抓出了那个鬼,于是想应对策略,既然这样,只要保证在cms gc回收old之前做一次ygc就能保证新生代里的那个新数组被回收而没有指向老生代那些byte数组,那么这些数组就能正常被cms gc回收了,所以加上-XX:+CMSScavengeBeforeRemark即可解此问题。

一起来学习吧:

PerfMa KO 系列课之 JVM 参数【Memory篇】

实战:OOM 后我如何分析解决的

又抓了一个导致频繁GC的鬼--数组动态扩容的更多相关文章

  1. 频繁GC会造成卡顿

    频繁GC会造成卡顿 https://www.cnblogs.com/qcloud1001/p/9525078.html 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求 ...

  2. 面试被问怎么排查平时遇到的系统CPU飙高和频繁GC,该怎么回答?

    处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警.本文主要针对系统运行缓慢这 ...

  3. 生产环境碰到系统CPU飙高和频繁GC系统反应慢,你要怎么排查?(转)

    处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警.本文主要针对系统运行缓慢这 ...

  4. CPU飙高,频繁GC,怎么排查?

    处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警. 本文主要针对系统运行缓慢 ...

  5. 平时碰到系统CPU飙高和频繁GC,你会怎么排查?

    处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警.本文主要针对系统运行缓慢这 ...

  6. FGC频繁 GC卡顿

    https://mp.weixin.qq.com/s/I1fp89Ib2Na1-vjmjSpsjQ 线上服务的FGC问题排查,看这篇就够了! 原创 骆俊武 IT人的职场进阶 2020-05-10   ...

  7. 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题

    背景起因: 记起以前的另一次也是关于内存的调优分享下   有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...

  8. JS垃圾回收——和其他语言一样,JavaScript 的 GC 策略也无法避免一个问题:GC 时,停止响应其他操作,这是为了安全考虑

    JavaScript 内存管理 & 垃圾回收机制 标记清除 js 中最常用的垃圾回收方式就是标记清除.当变量进入环境时,例如,在函数中声明一个变量,就将这个而变量标记为“进入环境”.从逻辑上讲 ...

  9. ########django-基于中间件写一个限制频繁登陆########

    django-基于中间件写一个限制频繁登陆 额额,标题已经很醒目了,通过中间件去实现,其他方法也可以实现 浏览器前端传来的请求,必须通过中间件,才能到后面路由,视图函数,所以我们在中间件那里做一层处理 ...

随机推荐

  1. Jaba_Web--JDBC 删除记录操作模板

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  2. RF(自定义关键字)

    1.在 D:\work_software\python\Lib\site-packages 文件夹下, 新建 python package 包 ,例如我的是 TestLibrary 建好后的完整路径: ...

  3. centos7 安装高版本svn

    一.安装高版本svn 1.创建一个新的yum库文件,vim /etc/yum.repos.d/wandisco-svn.repo 内容如下 [WandiscoSVN] name=Wandisco SV ...

  4. idea设置配置提示模板

    File-->Settings-->LIve Templates-->+-->Template Group(模板名称)-->Live Template

  5. STC8A8K64S4A12通过SPI接口操作基于ST7920的LCD12864液晶模块

    文章地址:https://www.cnblogs.com/jqdy/p/12665430.html 1. 硬件连接 1.1 64引脚的STC8A8K64S4A12 使用的是最小核心板,所以引脚皆引出可 ...

  6. spring data jpa 多对多 ManyToMany

    环境搭建 源码地址:gitee:https://gitee.com/ytfs-dtx/JPA 导入依赖 <properties> <spring.version>5.2.5.R ...

  7. Spring Cloud 系列之 Config 配置中心(三)

    本篇文章为系列文章,未读前几集的同学请猛戳这里: Spring Cloud 系列之 Config 配置中心(一) Spring Cloud 系列之 Config 配置中心(二) 本篇文章讲解 Conf ...

  8. python语法学习第三天--列表

    列表:python中不用定义类型,类似工厂 列表的创建: ①创建普通列表:[1,2],用逗号隔开 ②创建一个混合列表:[1,‘zyf',3.14,[1,2,3]] ③创建空列表:empty=[] 常用 ...

  9. [hdu2119]二分图最小覆盖,最大匹配

    题意:给一个01矩阵,每次可以选一行或一列,打掉上面所有的1,求打掉所有的1所需的最小次数. 思路:经典的模型了,二分图最小覆盖=最大匹配.所谓最小覆盖是指选最少的点关联所有的边.容易得到将行和列看成 ...

  10. 如何应对Kubernetes的安全挑战?

    导读:Kubernetes的广泛使用证明了企业的信念,即他们不仅具有处理现代应用程序开发和现代化计划的复杂性的能力,而且具有大规模处理能力. 根据CNCF对各种规模的公司中1340位技术专家的最新调查 ...