面试题答案
一键面试标记 - 清除算法
- 基本原理:
- 标记阶段:垃圾回收器从根对象(如栈中的引用、静态变量等)开始遍历,标记所有可达对象。
- 清除阶段:遍历堆内存,回收所有未被标记的对象,即不可达对象所占用的内存空间。
- 优点:
- 实现简单,不需要额外复杂的数据结构和算法,直接对堆内存进行两次遍历操作。
- 对于难以进行对象移动的场景(如存在指针指向对象内部特定位置等情况)较为适用。
- 缺点:
- 空间碎片化:回收后会产生大量不连续的内存碎片,当后续需要分配大对象时,可能无法找到足够连续的内存空间,即使总的空闲内存足够,也可能导致提前触发垃圾回收。
- 效率问题:标记和清除两个阶段的效率都不高,尤其是当堆内存很大时,遍历整个堆的开销较大。
复制算法
- 基本原理:
- 将堆内存划分为两块大小相等的区域,每次只使用其中一块(称为From空间)。
- 当From空间快满时,垃圾回收器从根对象开始遍历,标记所有可达对象,并将这些可达对象复制到另一块区域(称为To空间),同时保持对象之间的相对顺序。
- 复制完成后,直接清理From空间,此时From空间和To空间角色互换,原来的To空间成为新的From空间,原来的From空间成为新的To空间。
- 优点:
- 高效:只需对存活对象进行复制操作,相比标记 - 清除算法,不需要对整个堆进行两次遍历,尤其是在对象存活率较低的情况下,效率较高。
- 不会产生内存碎片:因为是将存活对象紧凑地复制到另一块空间,所以内存是连续的,后续分配大对象时不会因为内存碎片化而出现问题。
- 缺点:
- 空间浪费:堆内存需要划分成两块,只有一半的空间能被实际使用,造成了空间利用率的降低。
- 对象存活率高时效率低:如果存活对象较多,复制操作的开销会很大,因为需要复制大量对象到另一块空间,这会消耗较多的时间和资源。
标记 - 整理算法
- 基本原理:
- 标记阶段:与标记 - 清除算法类似,从根对象开始遍历,标记所有可达对象。
- 整理阶段:将所有存活对象(即被标记的对象)向一端移动,然后直接清理掉边界以外的内存空间,使存活对象占用的内存紧凑,且后续内存空间为连续的空闲空间。
- 优点:
- 解决内存碎片化问题:通过移动存活对象,使内存空间连续,避免了标记 - 清除算法产生的内存碎片问题,有利于后续大对象的分配。
- 空间利用率高:相比复制算法,不需要将堆内存划分成两块,空间利用率更高,特别是在对象存活率较高的场景下,优势明显。
- 缺点:
- 效率相对较低:整理阶段移动对象的操作比较复杂,需要调整对象的引用关系,并且移动对象的开销较大,尤其是在对象数量较多时,会影响垃圾回收的效率。
- 实现复杂度较高:相比标记 - 清除算法,需要额外处理对象移动和引用关系调整等逻辑,实现起来更加复杂。