1.强引用
平时所用的引用是强引用,特点是只有在引用消失的时候,gc才能回收强引用的对象
如:
public class StrongReference {
public static void main(String[] args) {
//强引用
Object o = new Object();
//1.此时引用依然存在,gc无法回收
System.gc();
o = null;
//2.引用不存在,gc可以回收该对象
System.gc();
}
}```
# 2.软引用
软引用特点是在发生gc时,不会马上回收该对象,只有在引用消失或者堆内存不足时,才会回收软引用的对象。主要用于缓存
如:
```java
/**
* jvm设置了最大堆内存20m用以验证: -Xmx20m
*/
public class SoftReference {
public static void main(String[] args) throws InterruptedException {
//创建一个占用10m内存的软引用
java.lang.ref.SoftReference<byte[]> sr = new java.lang.ref.SoftReference<byte[]>(new byte[1024*1024*10]);
//此时对象还在
System.out.println(sr.get());
//直接gc无法回收该对象
System.gc();
//此时对象依然还在
System.out.println(sr.get());
Thread.sleep(1000L);
//重新创建一个占用内存12m的数组,加上的10m已经大于堆最大值20m(注意不要太大,会内存溢出)
byte[] b = new byte[1024*1024*12];
//此时软引用对象已被回收(引用依然存在,但是对象被回收了)
System.out.println(sr.get());
}
}
结果:
[B@61bbe9ba
[B@61bbe9ba
null
3.弱引用
系统gc的时候会回收弱引用的对象。
ThreadLocalMap中的key是对ThreadLocal的弱引用,当线程不存在时(强引用消失),ThreadLocal对象会被回收。ThreadLocalMap中的value是强引用,需要手动调用ThreadLocal的remove()方法,或者等待下次调用set,remove方法时,jdk会自己去除key为null的value
如:
public class WeakReference {
public static void main(String[] args) {
//创建一个弱引用对象
java.lang.ref.WeakReference<Object> wr = new java.lang.ref.WeakReference(new Object());
//jvm未执行gc操作时,可以获取到该对象
System.out.println(wr.get());
//手动调用gc操作
System.gc();
//弱引用对象无法获取到,gc操作会回收弱引用对象
System.out.println(wr.get());
}
}
结果:
java.lang.Object@61bbe9ba
null
4.虚引用
引用无法获取到,主要是用于NIO(堆外内存)