Java虚拟机知识点【GC】

匿名 (未验证) 提交于 2019-12-02 21:52:03
  1. 标记-清除算法
    效率不高,而且存在内存碎片的问题。

  2. 复制算法

  3. 标记-整理算法

  4. 分代收集算法



  1. 新建的对象优先分配在Eden区;
  2. 当Eden区满了,就会触发Minor GC,Eden中的存活对象被移动到Survivor0,Eden被清空;
  3. 等Eden区再满了,再次触发Minor GC,Eden和Survivor0中的存活对象又会被复制到Survivor1,S0和Eden被清空,然后下一轮S0与S1交换角色,如此循环往复。
  4. 当两个Survivor区切换了几次(HotSpot虚拟机默认15次)之后,仍然存活的对象,将被复制到老年代。

Minor GC:发生在新生代的GC,因为Java对象都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
Major GC/Full GC:发生在老年代年的GC,出现Full GC经常伴随至少一次的Minor GC(非绝对,如Parallel Scavenge)。Full GC的速度一般会比Minor GC慢10倍以上,所以要合理设置年轻代与老年代的大小,尽量减少Full GC的操作。

  • 当Eden区满时触发。
  • 调用System.gc时,系统会建议执行Full GC,但是不一定执行。
  • 老年代空间不足时触发。
  • 方法区(永久代/元空间)空间不足时触发。
  • 通过Minor GC后进入老年代的平均大小大于老年代的可用连续内存时触发。
  • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用连续内存小于该对象大小时触发。
  • 对象优先在Eden区分配

    一次Minor GC。

  • 大对象直接进入老年代

  • 长期存活的对象将进入老年代

  • 动态对象年龄判定

  • 空间分配担保

  1. Serial:单线程的收集器。==复制算法==
  2. ParNew:Serial 收集器的多线程版本。==复制算法==
  3. Parallel Scavenge:类似ParNew的收集器,其他收集器关注于尽可能缩短 Stop The World 的时间, 而Parallel 收集器更关注系统的吞吐量,支持自适应调节策略。==复制算法==
  4. Serial Old:Serial 收集器的老年代版本。==标记整理算法==
  5. Parallel Old:Parallel Scavenge 收集器的老年代版本。==标记整理算法==
  6. CMS:Concurrent Mark Sweep 收集器是一种以获取最短回收停顿时间为目标的收集器。==标记清除算法==

  • 初始标记(Initial Mark):标记出老年代里面存活的对象,这些对象或者是从GC roots直接指向的,或者是被年轻代存活对象指向的。会导致 STW,速度最快。

  • 并发标记(Concurrent Mark):从上个阶段找到的所有根节点开始遍历整个老年代,标记存活的对象。速度慢,但是是和程序并发执行的。

  • 重新标记(Final Remark):由于之前的并发标记是并发过程,可能无法赶上应用程序的修改速度。所以需要重新标记来完成标记整个老生代存活对象的标记。会导致 STW,速度快。
  • 并发清除(Concurrent Sweep):并发清除死亡的对象。速度慢,但是是和程序并发执行的。

  • CPU资源非常敏感。CMS默认回收线程数是(CPU数量+3)/4。
  • 无法处理浮动垃圾,可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。CMS并发清理阶段用户线程还在运行,伴随程序运行自然有新的垃圾不断产生,这部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只好留到下次GC再清理。这部分垃圾就是浮动垃圾。因为垃圾收集阶段的用户线程还要运行,所以CMS不像其他收集器那样等老年代几乎填满了在收集,会预留一部分空间。-XX:CMSInitiatingOccupancyFraction可以设置触发的百分比。当预留的内存无法满足程序需要,就会出现出现“Concurrent Mode Failure”失败,此时,虚拟机启动后备方案:临时启用Serial Old。
  • 标记-清除算法的缺陷。易产生内存碎片。解决方法:通过参数配置,用于CMS在Full GC 时开启内存碎片的合并整理过程,内存整理过程无法并发,会导致STW时间变长,因此有另一个参数配置,用于设置执行多少次不压缩的Full GC后,执行压缩会Full GC。

7.G1:面向服务端应用。

  • 并发与并行:充分利用多CPU、多核环境的硬件优势,缩短STW。
  • 分代收集:保留分代概念,能独立管理整个GC堆。
  • 空间整理:基于“标记-整理“,局部(两个Region)上看基于“复制”算法。所以不会产生内存空间碎片。
  • 可预知的停顿:这是G1相对于CMS的另一大优势,能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

  • 初始标记(Initial Mark):类似CMS
  • 并发标记(Concurrent Mark):类似CMS
  • 最终标记(Remark):类似CMS
  • 筛选回收(cleanp):在此阶段将对象从一个或多个区域复制到单一区域,同时整理和释放内存。

8.ZGC:JDK 11 引入的,号称具有更低延迟的垃圾收集器,利用有色指针、加载屏障等技术,将 STW 控制在一次,只做一次扫描就能实现垃圾收集。

参数 功能
-XX:+UseConcMarkSweepGC 自动启用-XX:+UseParNewGC
-XX:+UseParallelGC 自动启用-XX:+UseParallelOldGC。Server模式下的默认值。
-XX:+UseParallelOldGC 自动启用-XX:+UseParallelGC
-XX:+UseParNewGC JDK8不能单独启用
-XX:+UseSerialGC Serial + Serial Old。Client模式下的默认值。
-XX:+UseG1GC 使用G1垃圾收集器

参考资料:《深入理解Java虚拟机(第二版)》、《Java虚拟机规范(Java SE 8版)》、GC Algorithms: Implementations

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!