JavaJava 杂谈技术干货

浅谈GC

2019-06-05  本文已影响62人  Jason_Sam

为什么要了解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

4. G1

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

5. ZGC

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

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

上一篇 下一篇

猜你喜欢

热点阅读