浅谈GC

作者: Jason_Sam | 来源:发表于2019-06-05 01:41 被阅读62次

为什么要了解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,等大堆内存。
  • 压缩整理:对象回收后会整理压缩内存空间,防止内存碎片问题。

相关文章

  • 浅谈GC

    为什么要了解GC 对于Java程序猿来说,内存分配与释放都交给JVM处理,而更多的精力能够投入到业务开发中去,这也...

  • GC浅谈(一)

    人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。-部尔卫 Java语言的一大特点就是可以进行自动垃圾回收...

  • GC浅谈(二)

    最糟糕的是人们在生活中经常受到错误志向的阻碍而不自知,真到摆脱了那些阻碍时才能明白过来。 —— 歌德 1. 对象的...

  • GC浅谈(三)

    人生并不像火车要通过每个站似的经过每一个生活阶段。人生总是直向前行走,从不留下什么。 —— 刘易斯 GC日志理解 ...

  • 浅谈GC机制

    一、什么是GC 在Java中,对象所占用的内存在对象不再使用后会自动被回收。这些工作是由一个叫垃圾回收器 Garb...

  • golang GC浅谈

    GC 回到正题:什么是GC?为什么需要GC,说到这个问题之前,需要了解的是相对底层语言:C++、C都是可以直接和操...

  • Java 垃圾收集(GC)浅谈

    Java 垃圾收集(GC)浅谈 为什么需要垃圾回收?哪些内存需要回收?什么时候回收?如何回收? 为什么需要垃圾回收...

  • 内存优化(三)Android对象池使用

    概述 由内存优化(一)浅谈内存优化中看出,内存优化不仅要从防止内存泄露入手,也要注意频繁GC卡顿,内存抖动以及不必...

  • JAVA教程:浅谈JVM的优化

    浅谈JVM的优化 前言 前面我们了解过JVM中堆的GC分代回收机制,在运行Java程序时,我们可以使用JVM的参数...

  • 浅谈GC垃圾回收机制

    首先,说一下为什么要进行GC垃圾回收手机内存给每个因公分配的内存都是有限的,如果频繁创建对象,而没有对无用对象进行...

网友评论

    本文标题:浅谈GC

    本文链接:https://www.haomeiwen.com/subject/rzbdxctx.html