垃圾回收——GC算法

一、Java对象在内存中的状态

1)可达的/可触及的

Java对象被创建后,如果被一个或多个变量引用,就是可达的

2)可恢复的

Java对象不再被任何变量引用就进入可恢复状态
在回收该对象前,如果在finalize()方法中重新让变量引用该对象,则该对象再次变为可达状态,否则进入不可达状态

3)不可达的

Java对象不被任何变量引用,且在调用对象的finalize()方法后依然没有变成可达状态
当对象处于不可达状态时,系统才会真正回收该对象占有的资源

二、垃圾对象的判定

1)可达性判断

单条引用路径可及性判断:在这条路径中,最弱的一个引用决定对象的可及性
多条引用路径可及性判断:在多条路径中,最强的一个引用决定对象的可及性

2)可达性分析法

  • 过程:从GC Roots开始向下查询,如果一个对象到任何一个GC Root对象都没有一个引用链相连的话,说明此对象不可用

Java语言是通过可达性分析算法来判断对象是否存活的

四个GC Root对象

  1. JVM栈中引用的对象
  2. 方法区静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地栈中JNI中引用的对象

3)引用计数法

  • 过程:给每个对象一个引用计数器,每当有一个地方引用它时,计数器就会加1;当引用失效时,计数器的值就会减1;任何时刻计数器的值为0的对象就是不可能再被使用的

优点:

  1. 可即刻回收垃圾,每个对象都知道自己的被引用数,当counter为0时,对象就会把自己作为空闲空间连接到空闲链表,也就是在对象变成垃圾的同时就会被回收.
  2. 最大暂停时间短,每次通过指向mutator生成垃圾时,这部分垃圾都会被回收,大幅削减了mutator的最大暂停时间

缺点:

  1. 计数器值的增减处理非常繁重
  2. 计算器需要占用很多位
  3. 实现繁琐
  4. 循环引用无法回收

三、垃圾回收算法

1)标记-清除(Mark-Sweep)

  • 过程:标记可回收对象,进行清除
  • 优点:占用内存小
  • 缺点:标记和清除效率低,清除后会产生内存碎片

2)复制算法

  • 过程:将内存划分为相等的两块,将存活的对象复制到另一块内存,把已经使用的内存清理掉
  • 优点:空间连续,没有内存碎片,运行效率高
  • 缺点:使用的内存变为了原来的一半

进化

  • 将一块内存按8:1的比例分为一块Eden区(80%)和两块Survivor区(10%)
  • 当对象在 Eden出生后,经过一次Minor GC 后,如果对象还存活,则将这些对象从 EdenSurvivor-From 复制到 Survivor-To ,然后清理 EdenSurvivor-From 区域,并将对象的年龄+1,当对象的年龄达到某个值时 ( 默认是 15岁,通过-XX:MaxTenuringThreshold 来设定参数),这些对象就会成为老年代
  • Survivor-To 区空间不足,则使用分配担保机制存入老年代。

3)标记-整理/标记-压缩(Mark—Compact)

  • 过程:所有存活的对象向一端移动,然后清除掉边界以外的内存

4)分代收集算法

  • 过程:将堆分为新生代和老年代,根据区域特点选用不同的收集算法,如果新生代朝生夕死,则采用复制算法,老年代采用标记清除,或标记整理

四、GC收集器

在这里插入图片描述

新生代收集器

1)Serial

单线程收集,非单核服务STW(stop the world)比较长,在工作的时候的时候会暂停所有的用户线程,采用 复制算法

2)ParNew

Serial收集器的多线程版本,也需要STW,使用 复制算法,跟老年代CMS收集器一起使用

3)Parallel Scavenge

跟ParNew类似,并行多线程,使用 复制算法

“吞吐量”=(用户线程执行时间)/(用户线程执行时间+gc执行时间)

注重用户代码运行时间而不是减少GC停顿时间。相对于其他收集器来说,可以更加高效的利用CPU,更加适合作为在后台运算而不大需要交互的任务。Parallel收集器提供了两个比较重要的参数。

-XX:MaxGCPauseMillis:表示收集器将尽可能的在这个参数设定的毫秒数内完成回收工作。但这并不代表其设置的越低越好,缩减回收时间是通过减少吞吐量换来的,如果设置得太低可能导致频繁的GC。

-XX:GCTimeRatio:表示代码运行时间和垃圾回收时间的比率,比如说设置为19,那么则垃圾回收时间占比为 1 / (1+19) = 5%,默认是99。

老年代收集器

1)Serial Old

是Serial收集器的老年代版本,单线程收集器,使用 标记-整理算法

2)Parallel Old

是Parallel Scavenge收集器的老年代版本,使用多线程,使用标记-整理算法

3)CMS

使用标记-清除算法,会产生碎片

CMS: 大体分为4个步骤

  1. 初始标记:需要STW,标记直接与GCRoots 相关连的对象,耗时较短
  2. 并发标记:不用STW,寻找堆中的死亡对象,整个过程耗时最长
  3. 重新标记:需要STW,标记 新生代可达且引用老年代的对象,还有刚进来老年代的对象
  4. 并发清除:不用STW,清除老年代没有做标记的对象(和用户线程一起执行的)

G1收集器

标记-整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选标记。不会产生空间碎片,可以精确地控制停顿。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值