把周末的文章放在现在才来写,是自己太忙了?还是堕落了?
好吧直接进入主题吧,简单干脆的理解会让自己记忆深刻:
首先说明:GC垃圾收集器关注两件事情:
第一件:查找所有存活对象。
第二件:抛弃死对象(不再使用的对象)。
然后再分步骤解释这个过程:
第一步, 记录所有的存活对象, 在垃圾收集中有一个叫做 标记(Marking) 的过程专门干这件事。
GC遍历内存中整体的对象关系图(object graph),从GC根元素开始扫描, 到直接引用,以及其他对象(通过对象的属性域)。所有GC访问到的对象都被标记(marked)为存活对象。
注意:在标记阶段,需要暂停所有应用线程, 以遍历所有对象的引用关系。因为不暂停就没法跟踪一直在变化的引用关系图。这叫做 Stop The World pause (全线停顿)。
第二步,GC删除不可达对象。
GC算法在删除不可达对象时略有不同,总结如下:
1、标记-清除算法:直接忽略所有的垃圾。也就是说在标记阶段完成后, 所有不可达对象占用的内存空间, 都被认为是空闲的, 因此可以用来分配新对象。
优点:非常简单。
缺点:容易导致内存分配失败。
2、标记-清除-整理算法:将所有被标记的对象(存活对象), 迁移到内存空间的起始处, 消除了标记-清除算法的缺点。
优点:解决了内存分配失败。
缺点:GC暂停的时间增长,需要将所有的存活对象移动到另一个地方。
3、标记-清除-复制算法:将将所有被标记的对象(存活对象)移动到另外一个空间: 存活区。
优点:标记和复制可以同时进行。
缺点:需要一个额外的内存区间来存放所有的存活对象。