JVM垃圾回收篇-垃圾回收算法
标记清除(Mark Sweep)
概念
collector
指的就是垃圾收集器。
mutator
是指除了垃圾收集器之外的部分,比如说我们的应用程序本身。mutator的职责一般是NEW(分配内存)、READ(从内存中读取内容)、WRITE(将内容写入内存),而collector则就是回收不在使用的内存来供mutator进行NEW操作的使用
步骤
- 在标记阶段collector从mutator根对象开始进行遍历,对从mutator根对象可以访问到的对象都打上一个标识,一般是
在对象的header中,将其记录为可达对象 - 而在清除阶段,collector对堆内存(heap memory)从头到尾进行线性遍历,如果发现某个对象没有被标记为可达对象,通过读取对象的header信息,将其回收。一种可行的实现是,在标记阶段首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后在清除阶段清除所有未被标记的对象
优缺点
标记清除算法清除阶段不会对内存进行置0操作,而是将空闲内存的地址加入空闲内存地址列表中,等下次使用时直接使用,但是由于这些内存是不连续的,总内存大小可能很大,但是实际被分为很多小段
- 优点是速度较快
- 缺点是会造成内存碎片
标记整理(Mark Compact)
标记操作和 "标记 - 清除" 算法一致,后续操作不只是直接清理对象,而是在清理无用对象完成后让所有存活的对象都向一端移动,并更新引用其对象的指针
优缺点
优点:没有内存碎片
缺点:速度慢
复制(Copy)
将内存空间分为相等的两部分,正在使用的区为FROM
,空闲区为TO
- 当from区内存空间不足时,将from区的存活对象先标记然后复制到to区,并清理form区的垃圾
- 交换from区和to区,即当前的form变为to,当前的to变为form
优缺点
优点:不会有内存碎片
缺点:需要占用双倍的内存空间
分代垃圾回收
-
对象首先分配在伊甸园区域
-
新生代空间不足时,触发
minor gc
,伊甸园和 from 存活的对象使用 copy 复制到 to 中,存活的对象年龄加 1并且交换 from to -
minor gc
会引发 stop the world,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行 -
当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)
-
当老年代空间不足,会先尝试触发
minor gc
,如果之后空间仍不足,那么触发full gc
,STW的时间更长