Week 9 作业
请简述 JVM 垃圾回收原理。
1 如何辨别一个对象已死亡
可达性分析算法
通过一系列称为GC Roots的对象作为起始点,然后向下搜索,走过的路径为引用链,如果一个对象到GC Roots 没有任何引用链,则说明此对象是不可达(不可用)的。
2 垃圾回收算法
2.1 标记-清除算法
标记-清除算法分为“标记”和“清除”两个阶段,执行过程如下图所示:
标记:首先标记出所有需要回收的对象
清除:在标记完成后统一回收所有被标记的对象
标记-清除算法主要有两个不足:
效率问题,标记和清除的两个过程效率都不高
标记-清除会产生大量不连续的内存碎片,这会导致在后面需要分配连续的大对象时,无法找到足够大的连续内存而导致不得不提前触发另一次垃圾收集动作
2.2 复制算法
复制算法的大致思路如下,其执行过程如下图所示:
首先将可用内存分为大小相等的两块,每次只使用其中的一块。
当这一块的内存用完了,就将还存活的对象连续复制到另一块上面,然后把使用过的内存空间一次清理掉
复制算法的代价就是将内存缩小为原来的一半。
现在的商业虚拟机都是采用复制算法来回收新生代。
新生代的内存分为一块较大的Eden空间和两块较小的Survivor空间。
每次使用Eden和一块Survivor,当进行回收是,将Eden和Survivor中还存活的对象一次性复制到另一个Survivor空间上。然后,清理掉Eden和刚刚使用过的Survivor空间。
HotSpot虚拟机默认Eden和Survivor的大小比例为8 : 1,这样每次新生代可用内存为整个新生代的90% (10% + 80%),只有10%的内存会被浪费。
2.3 标记-整理算法
标记-整理算法分为“标记”和“整理”两个阶段,执行过程如下图所示:
标记:首先标记出所有需要回收的对象
整理:让所有的存活的对象都向一端移动,然后直接清除掉边界以外的内存
2.4 分代收集算法
分代收集算法就是降Java堆分为新生代和老年代,根据其各自的特点采用最适当的收集算法。
新生代中大批对象死去,只有少量存活,就选用复制算法
老年代中对象存活几率高,没有额外的空间对它进行分配担保,就必须使用标记-清除或者标记-整理算法。
JVM垃圾收集器发展历程大致可以分为以下四个阶段: Serial(串行)收集器 -> Parallel(并行)收集器 -> CMS(并发)收集器 -> G1(并发)收集器
评论