浅谈GC

为什么要了解GC

对于Java程序猿来说,内存分配与释放都交给JVM处理,而更多的精力能够投入到业务开发中去,这也是Java能够受广大开发者欢迎的重要原因之一。但问题来了,万一程序出现内存泄漏和内存溢出问题怎么排查,如何定位问题,所以防患于未然,了解JVM的GC原理是每位Java开发者的职业素养。

对象实例收集算法

1.引用计数算法

顾名思义,就是为对象添加一个引用计数,用于记录对象被引用的次数,对象引用计算为0,则表示对象可回收。Java并没有选择引用计数机制,因为它不可解决循环引用的问题。

2.可达性分析

Java选择的是可达性分析算法。其原理是将对象及其引用看作一个关系图,选定对象作为GC Roots,然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是说不存在引用链条,那么即可认为是可回收对象。JVM会把虚拟机栈和本地方法栈中引用的对象、静态属性引用的对象和常量,作为GC Roots。

可达性分析

如图,GC Roots作为实例对象,obj1、obj2、obj3、obj4与GC Roots存在引用链条,而obj5、obj6、obj7与GC Roots不存在引用链条,呢么obj5、obj6、obj7则被视为可回收对象。

GC算法

1.标记清除算法(Mark-Swap)

分为两个阶段:标记和清除。标记阶段的工作是标记可回收对象的内存。清除阶段的工作是清除已标记的内存。

优点:效率高。

缺点:多次清除后,会产生大量的内存碎片

标记清除算法

2.复制算法(Copying)

按内存容量分为两部分:已使用和未使用。把已使用部分的存活对象复制到未使用部分,统一回收已使用部分的全部空间,那么就不会出现Mark-Swap算法的内存碎片问题。

优点:效率高、保持内存的最大可用性。

缺点:当存活数量较多的时候,效率会骤降。

复制算法

3.标记整理算法(Mark-Compact)

分为两个阶段:标记和整理。标记阶段和Mark-Swap阶段一样。整理阶段工作是把存活对象移向一端,统一处理可回收内存,解决了Copying算法和Mark-Compact算法的结构弊端。

优点:保持内存的最大可用性。

缺点:效率低。

标记整理算法

垃圾收集器

1. 比较应用

收集器 作用年代 线程状态 算法 特点 场景
Serial 新生代 串行 复制 响应速度优先 单CPU环境下的Client模式
ParNew 新生代 并行 复制 响应速度优先 多CPU环境Server模式下与CMS配合使用
Parallel Scavenge 新生代 并行 复制 吞吐量优先 适用于后台运算而且不需要太多交互的场景
Serial Old 老年代 串行 标记-整理 响应速度优先 单CPU环境下的Client模式
Parallel Old 老年代 并行 标记-整理 吞吐量优先 适用于后台运算而不需要太多交互的场景
CMS 老年代 并行 标记-清除 响应速度优先 适用于互联网或者B/S业务
G1 新生代/老年代 并行 标记-整理算法+复制算法 响应速度优先 面向服务器端应用
ZGC 不分代Region 并发 着色指针
+读屏障
+压缩整理
处理大堆 面向服务器端应用

2. 分代关系与实用

新生代 老年代 JVM参数
Serial Serial Old -XX:+UseSerialGC
Parallel Scavenge Serial Old -XX:+UseParallelGC
Parallel Scavenge Parallel Old -XX:+UseParallelOldGC
ParNew Serial Old -XX:-UseParNewGC
ParNew CMS+Serial Old -XX:+UseConcMarkSweepGC
G1 G1 -XX:+UseG1GC

注:

Java8新生代默认Parallel Scavenge,老年代默认Parallel Old

Java9默认是G1

3. CMS

  • 初始标记:标记Root直接可达对象,会STW。
  • 并发标记:标记所有可达对象。
  • 重信标记:二次标记,时间比并发时间短,但比初始标记时间长,会SWT。
  • 并发清理:清理已经死亡的对象。
  • 并发重置:为下次GC重置数据结构。

4. G1

没有物理化的年代区分,都是对象都是一个个Region,保持高回收率减少停顿,是逻辑分代管理,分为年轻代、老年代、矩形对象。G1会全局扫描。

  • 年轻代:使用并行复制算法清除对象。
  • 老年代:使用标记整理方法清除对象,由于不是全局清除,是局部清除所以STW的时间短。
    • 初始标记(SWT):同CMS
    • 并发标记:同CMS
    • 最终标记(SWT):同CMS
    • 复制/清除(SWT):优先回收可回收空间较大的Region(G garbage First),每次只清理一部分,而不是全局清理。

5. ZGC

特点:能做到10ms以下的回收停顿时间,支持TB级别的对象回收。

过程:划分许多大小不一的Region,然后通过短暂的SWT标记Roots对象,并发通过着色指针的标记可回收对象(边缘情况可能SWT),并发清除后进行并发重定位。

  • 着色指针:在64位OS中,最大支持4TB的堆占用42位,剩下22位可用作其他用途,目前只使用了4位着色指针标记。
  • 读屏障:为了解决用户线程和GC线程并发导致对象状态的问题,减少SWT。
  • 并发执行:由于读屏障的支持,大部分之间都是并发执行的。
  • 基于Region:没有固定大小的Region,所以对象大小可支持TB,等大堆内存。
  • 压缩整理:对象回收后会整理压缩内存空间,防止内存碎片问题。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原文阅读 前言 这段时间懈怠了,罪过! 最近看到有同事也开始用上了微信公众号写博客了,挺好的~给他们点赞,这博客我...
    码农戏码阅读 6,131评论 2 31
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 16,024评论 3 83
  • JVM架构 当一个程序启动之前,它的class会被类装载器装入方法区(Permanent区),执行引擎读取方法区的...
    cocohaifang阅读 1,821评论 0 7
  • 声明:原创文章,转载请注明出处。http://www.jianshu.com/u/e02df63eaa87 垃圾收...
    唐影若凡阅读 1,143评论 1 6
  • 来自: Android梦想特工队作者: Aaron主页: http://www.wxtlife.com/原...
    技术特工队阅读 4,587评论 0 28

友情链接更多精彩内容