对象引用类型
强引用
被强引用关联的对象不会被回收。
1 | Object obj = new Object(); |
软引用
被软引用关联的对象只有在内存不够的情况下才会被回收。
作用: 缓存
1 | Object obj = new Object(); |
// ===== 软引用测试(-Xms:20M -Xmx20M) =====
SoftReference<byte[]> m = new SoftReference<>(new byte[1024102410]);
System.out.println(m.get());// 再分配一个数组,heap 将装不下,这时候系统会垃圾回收,先回收一次,如果不够,会把软引用干掉
byte[] b = new byte[1024102415];
System.out.println(m.get()); // null
弱引用
被弱引用关联的对象一定会被回收,也就是说它只能存活到下一次垃圾回收发生之前。
作用: 一般用在容器里。强引用和弱引用同时指向某个对象,当强引用不再指向该对象时,该对象就该被回收
例:ThreadLocal 对象 new 后有强引用,而当前线程中的 ThreadLocalMap 对象的键也有 ThreadLocal 对象的弱引用,所以当 ThreadLocal 对象失去强引用时 ThreadLocalMap 中对应的键也会变为 null,防止了内存泄露。虽然 ThreadLocalMap 的键为 null 了,但是其 value 值还存在所以依然会有内存泄露,所以需要执行 ThreadLocal#remove 方法
1 | Object obj = new Object(); |
WeakReference
m = new WeakReference<>(new M()); System.out.println(m.get());
System.gc();
System.out.println(m.get()); // nullThreadLocal
tl = new ThreadLocal<>();
tl.set(new M());
tl.remove();
虚引用
又称为幽灵引用或者幻影引用。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象。
作用:
- 为一个对象设置虚引用关联的唯一目的就是能在这个对象被回收时收到一个系统通知。
- 管理堆外内存(通常给编写 JVM 的人使用):DirectByteBuffer 对象指向堆外内存。当 DirectByteBuffer 被回收时,可以通过队列检测到,然后清理堆外内存
1 | // 关联了对象和队列 |