GC整理

GC整理

  • GC分类

    • 在Hotspot VM实现中,主要有两大类GC
      • Partial GC
        • young gc:只收集 young gen 的GC
        • old gc:只收集 old gen 的GC,只有CMS的 concurrent collection
        • mixed GC:收集整个 young gen 以及部分 old gen 的GC,只有G1
      • Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等
      • 其实在各种文章或书上还可以看到Minor GC、Major GC的字眼,其中minor GC和young gc对应,而Major GC通常是和Full GC是等价的,由于HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了,所以Major GC有时也可能是指old gc,在下定论之前一定要先问清楚。
  • 单线程、并行、并发 (在GC收集器实现中,分为了单线程、并行和并发。)

    • 单线程收集器:如 Serial GC,这个比较好理解,即垃圾收集过程中只有单一线程在进行收集工作,实现也最简单。
    • 并行收集器:如Parallel GC,每次运行时,不管是YGC,还是FGC,会 stop-the-world,暂停所有的用户线程,并采用多个线程同时进行垃圾收集。
    • 并发收集器:如CMS GC,在新生代进行垃圾收集时和并行收集器类似,都是并行收集(当然具体算法中,你也可以设置成采用单线程进行收集),而且都会stop-the-world,主要的区别在于老年代的收集上,CMS在老年代进行垃圾收集时,大部分时间可以和用户线程并发执行的,只有小部分的时间stop-the-world,这就是它的优势,可以大大降低应用的暂停时间,当然也是有劣势的。
  • 算法组合 (Hotspot VM实现的几种GC算法组合中,其中CMS GC使用最广,因为现在都是大内存时代)

    • Serial GC
      • Serial generational collector (-XX:+UseSerialGC)是全局范围的Full GC,这种算法组合是最早出现的,当年的Java堆内存大小都还不大,使用Serial GC进行单线程收集,还感觉不出来GC耗时导致应用暂停的问题
    • ParNew - Parallel GC
      • Parallel for young space, serial for old space generational collector (-XX:+UseParallelGC).Parallel for young and old space generational collector (-XX:+UseParallelOldGC)当Java堆慢慢变大时,发现已经无法忍受GC耗时带来的应用暂停了,出现了Parallel GC,采用多线程的方式进行垃圾收集,很明显可以提升垃圾收集效率。
    • CMS GC
      • Concurrent mark sweep with serial young space collector (-XX:+UseConcMarkSweepGC –XX:-UseParNewGC) Concurrent mark sweep with parallel young space collector (-XX:+UseConcMarkSweepGC) 当Java堆达到更大时,比如8G,使用Parallel GC带来的应用暂停已经很明显了,所有又出现了 CMS GC,这是目前我看到线上环境使用的比较多的GC策略,在参数中添加-XX:+UseConcMarkSweepGC,对于 young gen,会自动选用 ParNewGC,不需要额外添加 -XX:+UseParNewGC。CMS虽然好,因为它的特殊算法,大部分的收集过程可以和用户线程并发执行,大大降低应用的暂停时间,不过也会带来负面影响,在收集完 old gen 之后,CMS并不会做整理过程,会产生空间碎片,如果这些碎片空间得不到利用,就会造成空间的浪费,整个过程中可能发生 concurrent mode failure,导致一次真正意义的 full gc,采用单线程对整个堆(young+old+perm) 使用MSC(Mark-Sweep-Compact)进行收集,这个过程意味着很慢很慢很慢,而且这个碎片问题是无法预测的.
  • 触发条件

    • young gc
      • 对于 young gc,触发条件似乎要简单很多,当 eden 区的内存不够时,就会触发young gc
      • 在 eden 区给对象分配一块内存是怎样一个过程
      • 在 eden 区分配空间内存不足时有两种情况,为对象分配内存、为TLAB分配内存,总之就是内存不够,需要进行一次 young gc 为eden区腾出空间为后续的内存申请做准备,然后由一个用户线程通知VM Thread,接下去要执行一次 young gc
    • full gc
      • old gen 空间不足
        • 当创建一个大对象、大数组时,eden 区不足以分配这么大的空间,会尝试在old gen 中分配,如果这时 old gen 空间也不足时,会触发 full gc,为了避免上述导致的 full gc,调优时应尽量让对象在 young gc 时就能够被回收,还有不要创建过大的对象和数组。
      • 统计得到的 young gc 晋升到 old gen的对象平均总大小大于old gen 的剩余空间
        • 当准备触发一次 young gc时,会判断这次 young gc 是否安全,这里所谓的安全是当前老年代的剩余空间可以容纳之前 young gc 晋升对象的平均大小,或者可以容纳 young gen 的全部对象,如果结果是不安全的,就不会执行这次 young gc,转而执行一次 full gc
      • perm gen 空间不足
        • 如果有perm gen的话,当系统中要加载的类、反射的类和调用的方法较多,而且perm gen没有足够空间时,也会触发一次 full gc
      • ygc出现 promotion failure
        • promotion failure 发生在 young gc 阶段,即 cms 的 ParNewGC,当对象的gc年龄达到阈值时,或者 eden 的 to 区放不下时,会把该对象复制到 old gen,如果 old gen 空间不足时,会发生 promotion failure,并接下去触发full gc
        • 在GC日志中,有时会看到 concurrent mode failure 关键字,这是因为什么原因导致的问题呢? 对这一块的理解,很多文章都是说因为 concurrent mode failure 导致触发full gc,其实应该反过来,是full gc 导致的 concurrent mode failure,在cms gc的算法实现中,通常说的cms是由一个后台线程定时触发的,默认每2秒检查一次old gen的内存使用率,当 old gen 的内存使用率达到-XX:CMSInitiatingOccupancyFraction设置的值时,会触发一次 cms gc,对 old gen 进行并发收集,而真正的 full gc 是通过 vm thread线程触发的,而且在判断当前ygc会失败的情况下触发full gc,如上一次ygc出现了promotion failure,如果执行 full gc 时,发现后台线程正在执行 cms gc,就会导致 concurrent mode failure。
      • 对于以上这些情况,CMSInitiatingOccupancyFraction参数的设置就显得尤为重要,设置的太大的话,发生CMS时的剩余空间太小,在ygc的时候容易发生promotion failure,导致 concurrent mode failure 发生的概率就增大,如果设置太小的话,会导致 cms gc 的频率会增加,所以需要根据应用的需求对该参数进行调优。
  • 一些命令

    • 执行 System.gc()、jmap -histo:live pid、jmap -dump ...
  • References

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • System.gc整理 System.gc()源码public static void gc() { Runtim...
    andersonoy阅读 2,855评论 0 1
  • 作者:一字马胡 转载标志 【2017-11-12】 更新日志 日期更新内容备注 2017-11-12新建文章初版 ...
    beneke阅读 2,165评论 0 7
  • 原文阅读 前言 这段时间懈怠了,罪过! 最近看到有同事也开始用上了微信公众号写博客了,挺好的~给他们点赞,这博客我...
    码农戏码阅读 5,878评论 2 31
  • 简书 占小狼转载请注明原创出处,谢谢 上周有幸给部门的小伙伴分享了一些JVM相关的知识,在整个做PPT的过程中,也...
    美团Java阅读 8,184评论 19 76
  • 声明:原创文章,转载请注明出处。http://www.jianshu.com/u/e02df63eaa87 1、J...
    唐影若凡阅读 1,017评论 0 6