前言
在JDK1.2以前的版本中,当一个对象不被任何变量引用,那么程序就无法再使用这个对象。
在JDK1.2只有,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,这四种引用强度依次逐渐减弱。
强引用
强引用就是指在代码中普遍存在的,类似“Object obj = new Object()”这样的引用,只要引用还存在,垃圾收集器永远不会回收掉被引用的对象
这里的不会回收,即便是内存不够,系统抛出OOM异常,被引用的对象也不会被回收。
/**
* @author Fibonacci
* @date 2020-12-26 19:16
*/
public class TestStrongReference {
@Override
public void finalize() {
System.out.println("对象被回收");
}
public static void main(String[] args) {
// 强引用
TestStrongReference testClass = new TestStrongReference();
// 手动置为null
testClass = null;
// 手动触发gc
System.gc();
// 等待垃圾回收完成
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 设置启动参数 -Xmx20M,测试强引用下的OOM
// new一个10M的对象
byte[] b1 = new byte[1024 * 1024 * 10];
// 再new一个15M的对象
// 由于b1是强引用,引用还在,不会被回收,再创建一个15M的对象,会OOM
byte[] b2 = new byte[1024 * 1024 * 15];
}
}
软引用
软引用用来描述一些还有用,但非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。
软引用可以当缓存使用。
import java.lang.ref.SoftReference;
/**
* @author Fibonacci
* @date 2020-12-26 19:40
*/
public class TestSoftReference {
public static void main(String[] args) {
// 设置启动参数 -Xmx20M
// 创建一个10M的软引用对象
SoftReference<byte[]> sr = new SoftReference<>(new byte[1024 * 1024 * 10]);
// 获取软引用的对象
System.out.println(sr.get());
// 手动触发gc
System.gc();
// 等待垃圾回收完成
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 内存够,软引用对象没有被回收,还能获取到
System.out.println(sr.get());
// 再new一个10M的对象
// 如果是强引用,sr占10M内存,此时再创建b1,会OOM
// 但sr是弱引用,当内存不足的时候,会回收sr的内存,这样b1就能成功创建
byte[] b1 = new byte[1024 * 1024 * 10];
// 再次获取软引用的对象,为null,已经被回收了
System.out.println(sr.get());
}
}
弱引用
弱引用也是用来描述非必须对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
import java.lang.ref.WeakReference;
/**
* @author Fibonacci
* @date 2020-12-26 19:40
*/
public class TestWeakReference {
public static void main(String[] args) {
// 创建弱引用
WeakReference<byte[]> wr = new WeakReference<>(new byte[1024 * 1024 * 10]);
System.out.println(wr.get());
// 手动触发gc
System.gc();
// 获取的结果为null,已经被回收
System.out.println(wr.get());
}
}
虚引用
虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。