面试题答案
一键面试1. 对象引用类型与可回收判定
- 强引用(Strong Reference):
- 只要对象有强引用指向,垃圾回收器永远不会回收它。只有当强引用被释放(例如将引用变量赋值为
null
),对象才可能被回收。 - 示例代码:
- 只要对象有强引用指向,垃圾回收器永远不会回收它。只有当强引用被释放(例如将引用变量赋值为
Object strongRef = new Object();
// strongRef 指向对象,对象不会被回收
strongRef = null;
// 此时对象失去强引用,可能会被回收
- 软引用(Soft Reference):
- 在系统内存充足时,软引用指向的对象不会被回收;当系统内存不足时,垃圾回收器会回收软引用指向的对象。常用于实现对内存敏感的缓存。
- 示例代码:
SoftReference<Object> softRef = new SoftReference<>(new Object());
Object obj = softRef.get();
if (obj != null) {
// 使用 obj
} else {
// 内存不足时,obj 可能已被回收
}
- 弱引用(Weak Reference):
- 只要垃圾回收器扫描到弱引用指向的对象,不管当前系统内存是否充足,都会回收该对象。弱引用常被用于解决内存泄漏问题,例如
WeakHashMap
。 - 示例代码:
- 只要垃圾回收器扫描到弱引用指向的对象,不管当前系统内存是否充足,都会回收该对象。弱引用常被用于解决内存泄漏问题,例如
WeakReference<Object> weakRef = new WeakReference<>(new Object());
Object obj = weakRef.get();
// 可能 obj 已经被回收,返回 null
- 虚引用(Phantom Reference):
- 虚引用对对象的生命周期没有影响,无法通过虚引用来获取对象实例。设置虚引用的唯一目的是在对象被回收时,收到一个系统通知。常用于对象销毁前的一些资源清理操作。
- 示例代码:
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);
Object obj = phantomRef.get();
// obj 始终为 null
// 当对象被回收时,虚引用会被放入 ReferenceQueue
2. 复杂对象图结构下垃圾回收判定
- 在复杂对象图结构中,垃圾回收器使用可达性分析算法。从一系列被称为 “GC Roots” 的对象作为起始点,通过引用关系向下搜索,所走过的路径称为引用链。如果一个对象到 GC Roots 没有任何引用链相连,则证明此对象是不可达的,会被判定为可回收对象。
- 示例代码:
class Node {
Node next;
public Node(Node next) {
this.next = next;
}
}
public class ComplexGraph {
public static void main(String[] args) {
Node head = new Node(null);
Node node1 = new Node(null);
Node node2 = new Node(null);
head.next = node1;
node1.next = node2;
// head 到 node2 有引用链
head = null;
// 此时 head 失去引用,若没有其他引用到 head 及其后续节点,这些节点都可能被回收
}
}
在上述代码中,当 head
被赋值为 null
后,如果没有其他地方持有对 node1
和 node2
的引用,那么从 GC Roots
出发无法到达这些节点,它们就会被判定为可回收对象。垃圾回收器会在合适的时候回收这些对象所占用的内存。