本文基于JDK 1.8,使用的收集器为ParNew + CMS

前言

这篇文章的起因是这样的,在上周五凌晨很苦逼得参加双十一压测值班的时候,有个业务方突然打电话来说我们提供的客户端存在内存泄漏问题导致线上应用持续full gc,本来已经快要睡着的我立马就精神起来了,一通排查,最终定位到了确实是客户端有个bug会导致部分数据会被一直持有进入老年代之后gc不掉,从而就导致了老年代的频繁gc,具体bug暂且不表,有一个很奇怪的现象引起了我的注意,那就是从监控系统上来看,这个应用平均一分钟full gc次数高达十多次,按照我之前的理解full gc时是会stop the world的,stop the world的频率这么高,那么应用自身的服务已经跪掉了啊,但是看这个应用的业务指标监控,居然一切正常,这就有点超出我的理解能力了,后面为了解决这个疑问,针对什么是full gc,以及如何查看full gc的次数等查阅了很多资料,总算搞懂了full gc这个概念,在查资料的过程中发现中文社区里面包含太多错误的信息了,而且大多都是抄来抄去的,非常误导人,因此打算写一篇文章,对一些错误观点进行纠正。

正文

前置知识点

在真正开始探索Full GC之前,我们需要先介绍几个概念

GC

GC 全称为garbage collection,中文含义为垃圾回收,在jvm中的含义为回收无用内存空间

Young space

中文名为年轻代或者新生代,为JVM 堆的一部分,由分代GC概念划分而来,保存生命周期较短的对象

Tenured space

中文名为老年代或年老代,为JVM 堆的一部分,由分代GC概念划分而来,保存生命周期较长的对象

Minor GC

minor gc指的是发生在年轻代或者说新生代(Young space)中的gc,也有人称其为young gc或者ygc,在下文中我们统一使用minor gc表示

Major GC

major gc指的是发生在老年代(Tenured space)中的gc,也有人称为old gc,o gc,cms gc等,在下文我们统一使用major gc表示

stop the world

指的是用户线程在运行至安全点(safe point)或安全区域(safe region)之后,就自行挂起,进入暂停状态,对外的表现看起来就像是全世界都停止运转了一样,而不论何种gc算法,不论是minor gc还是major gc都会stop the world,区别只在于stop the world的时间长短。

什么是Full GC

先说一下结论,Full GC这个概念是没有官方定义的,而且含义还特别混乱,在不同地方表达的含义是不同的,需要就不同的场景分别进行讨论。

大众认知上

在通常意义上人们口中说的Full GC为一次特殊GC行为的描述,这次GC会回收整个堆的内存,包含老年代,新生代,metaspace等,这个是最常见的一种认知,很多人也就了解到这个程度,因此在遇到一些特殊场景的时候就会发现实际情况和自己的认知会发生冲突

从GC日志上

在gc.log中会发现在部分gc日志头中也有Full GC这样的字眼,这里表示的含义是在这次GC的全过程中,都是Stop The world的状态,也就是说在这次GC的全过程中所有用户线程都是处于暂停的状态,那么在这里要喷一下中文jvm神书《深入理解JVM》了,在第二版第89页有这么一段话:

GC 日志开头的“[GC”和“[Full GC”说明了这次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC的。如果有“Full”,说明这次GC是发生了Stop-The-World的,例如下面这段新生代收集器ParNew的日志也会出现“[Full GC”(这一般是因为出现了分配 担保失败之类的问题 .所以才导致STW)。如果是调用System.gc()方法所触发的收集,那么在这里将显示“[Full GC (System)”。

这段话的描述是错误的,因为在前面说过,不论何种gc算法,不论新生代或是老年代,其gc都会发生stop the world,这里正确的描述是这次GC的全过程都是Stop-The-World的

从JDK自带的工具上

使用jstat -gc命令能够查看到制定java 线程的gc次数,那么在经过我的多次尝试以及对比之后,我发现了使用jstat 查出来的FGC 次数和时间,实际上指的是老年代的收集器发生Stop the world 的次数和持续时间,对应本文而言,就是CMS收集器的Stop the world次数和时间

其他含义(坑爹版)

前面不是说到我在监控大盘上看到这个应用平均一分钟发生了十多次”Full GC”么,在我弄明白了前面两个Full GC的含义之后查看了gc.log文件,随后发现该应用实际上一次Full GC都没有出现,然后咨询了一下提供监控数据的同学,结果他说是通过JMX获取的,代码为:

ManagementFactory.getGarbageCollectorMXBeans()

然后众所周知,使用MXBean获取到的只是收集器的执行次数,和Full GC半毛钱关系都没有啊,随后在追问了一下,发现做监控系统的同学直接把CMS收集器的收集次数当做了Full GC的次数来统计,what the fuck????,只能说对于FUll GC的概念真的有很多人是一直没弄懂过的

结束语

在这篇文章快写完的时候,用google随便搜了一下就在首页找到一篇对于各类gc概念介绍得比较透彻的文章,和使用度娘一搜首页全是各种抄来抄去的错误文章相比,对比简直是太强烈了,由此得出结论,技术类的资料能在外网查就在外网查吧,省时又省力,最后附上我找到的这篇文章貌似还是plumbr的联合创始人写的,不得不说很给力了

杂谈之什么是FullGC相关推荐

  1. 一次线上 JVM 调优实践,FullGC 40 次/天到 10 天一次的优化过程

    点击关注公众号,Java干货及时送达 来源 | https://blog.csdn.net/cml_blog/article/details/81057966 通过这一个多月的努力,将 FullGC ...

  2. gcore java_获取一直FullGC下的java进程HeapDump的小技巧

    小技巧 我们应用的java进程出问题的时候,我们往往会用jmap或者gcore拿到一份HeapDump,拿到MAT上做一次Heap分析,但是 如果你排查的是一直在FullGC的gc问题,你Dump下来 ...

  3. CMS发生FullGc分析

    fullgc的原因 Full GC触发条件: (1)System.gc()方法的调用 该方法不一定执行,但是执行的时候是fullgc. (2)老年代空间不足 老年代空间只有在新生代对象转入及创建为大对 ...

  4. 【杂谈】GAN最成功的3个商业化落地领域,你是否了解过?

    2015年的时候笔者开始关注GAN,公众号早期的文章中就有GAN的综述,这些年GAN的相关研究也是持续井喷.这一次咱们学术上的研究撇开不讲,这么多年过去了,GAN有哪些最成功的商业化落地领域? 图像生 ...

  5. 「杂谈」同学聚会最悲哀的事情

    「杂谈」同学聚会最悲哀的事情 大学毕业至今近乎20年了,期间参加过几次规模或大或小的同学聚会,有高中同学会聚会,初中同学聚会,也有大学同学聚会.这些同学聚会上,笔者发现其实体验都还很不错,基本没有发现 ...

  6. 「杂谈」计算机视觉人脸图像的十几个大的应用方向,你懂了几分?

    2020-02-16 13:45:50 文/编辑 | 言有三 人脸图像属于最早被研究的一类图像,也是计算机视觉领域中应用最广泛的一类图像,可以说掌握好人脸算法,基本就玩转了计算机视觉领域.在经历了几十 ...

  7. 杂篇-从整理文件发起的杂谈[-File-]

    有些东西很简单,简单到你不想去想,比如:为什么天是蓝的?--局限物语 零.前言 说一下本篇的初衷: coder盘作为工作盘有点乱,想整理一下 也想寻求一个方便管理工程的点子,既然File类玩的滚瓜烂熟 ...

  8. fullgc一小时发生一次的原因

    问题:之前在线上遇到过一个问题,每一小时都会执行fullgc,但是此时的堆内存大小是足够的. 分析: 当前我的tomcat的版本是6.0.35,此时tomcat有这样的配置: 6.0.35的org.a ...

  9. c语言会出现fullgc,以上述代码为基础,在发生过一次FullGC后,上述代码在He

    这是一个关于java的垃圾回收机制的题目.垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的.堆区分为三个区:年轻代(Young Generation).年老代(Old Generati ...

  10. Metaspace 引起的 FullGC 问题排查过程及解决方案

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 转载自公众号:字节观 关注我,回复口令获取可获取独家整理的学习资料: - 001 :领取<Spr ...

最新文章

  1. Linux 文件系统权限(一)
  2. 实现一个简单的文件上传进度条
  3. 20171101从现在开始就请有计划的学习吧!
  4. 深入了解softmax
  5. 测试的艺术:测试用例的设计
  6. jeecg中的树形控件demo
  7. U盘安装ubuntu 14.10遇到gfxboot.c32
  8. vue 圆形 水波_vue 开发波纹点击特效组件
  9. python的numpy教程_python numpy 基础教程 | 学步园
  10. 电子相册系统(八)验证用户是否可用
  11. NumberFormat和DecimalFormat
  12. siamfc代码解读_SiamFC算法改进思路
  13. php is numeric用法,PHP使用 is_numeric的实例解析
  14. 微信小程序 | 自动定时结束录制
  15. 【绝对经典】骂人口误.......................
  16. 隐藏的区别:display:none 和visibility:hidden
  17. linux 子程序返回错误代码,execvp:在程序中调子程序并获取返回值
  18. 会议通知html页面,【会议通知H5】送你最新会议邀请函H5教程,请点击查收!
  19. INTRINS.H的函数
  20. 公司的耍流氓行为,你知道几个?

热门文章

  1. 计算机键盘锁不了怎么办,笔记本电脑键盘没反应是哪个键锁了?该怎么办
  2. linux quota原理,[转载]linux下quota实现
  3. 自学java到可以找工作要多久_自学编程需要多久才能找到工作?
  4. 世界地图新西兰_世界地图新西兰的位置在哪里?新西兰与澳大利亚相隔多远?...
  5. java se 64位_【JavaSERuntime(jre864位版)免费版下载】Java SE Runtime(jre8 64位版) 8.0-ZOL软件下载...
  6. 【Web动画】SVG 线条动画入门
  7. python绘制跳棋棋盘
  8. Spring(26)——PathMatchingResourcePatternResolver
  9. 程序员的奋斗史(三十一)——人在囧途之应聘篇(一)
  10. 配置中心—Consul配置管理