前言
判断对象是否存活都与引用抛不开关系。而JDK1.2前的引用是很传统的意思。就比如某个数据中存储的值代表的是另一块内存的地址值,那么就说这个数据代表的是某个内存某个对象的引用。这种概念在某些情况下有点狭隘了。因为这种只代表了引用和非引用两种情况,而对于有些对象,留着没什么关系,丢了也不可惜,内存足够时我留着,内存不足时我丢弃,这样情况下的对象,这种引用的概念没法很好的描述。对此,在JDK1.2后,对引用进行了扩充,分别为:
强引用(Strongly Reference)
软引用(Soft Reference)
弱引用(Weak Reference)
虚引用(Phantom Reference)
强引用
最传统的引用定义。这种是在代码中普遍存在的引用。比如
Object o = new Object();
在这种的引用关系下,哪怕内存不足,垃圾回收器也不会回收。
软引用
软引用用于描述一些还有用,但是非必须的对象。这种情况下的引用,只有在内存快要溢出的时候,才会把这些对象纳入回收范围进行二次回收,如果这次的回收后内存还是不足,才会抛出异常。
通过SoftReference类实现软引用
看看例子:
先把设置JVM参数: -Xms3M -Xmx3M
用强引用
static List list = new ArrayList();
public static void main(String[] args) {
for (int i = 0;i<10;i++){
byte[] buff = new byte[1024 * 1024 * 1];
list.add(buff);
}
}
执行结果,报错:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
这是因为内存只有3M,但是一共会创建出10M的byte数组对象,内存不够报错。
这时换成软引用
static List list = new ArrayList();
public static void main(String[] args) {
for (int i = 0;i<10;i++){
byte[] buff = new byte[1024 * 1024 * 1];
SoftReference<byte[]> s = new SoftReference<>(buff); //加了这一句
list.add(s); //list添加的是软引用
}
}
执行结果没报错。
打印下byte对象看看
static List list = new ArrayList();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
byte[] buff = new byte[1024 * 1024 * 1];
SoftReference<byte[]> s = new SoftReference<>(buff);
list.add(s);
}
for (int i = 0; i < list.size(); i++) {
SoftReference s =(SoftReference)list.get(i);
System.out.println(s.get());
}
}
结果如下
null
null
null
null
null
null
null
null
null
[B@1b6d3586
前面9个因为内存不足被回收了。
弱引用
弱引用也是用来描述非必须的对象,强度比强引用更弱。当发生垃圾回收时,弱引用关联的对象都会被回收。用WeakReference来实现弱引用。代码如下:
static List list = new ArrayList();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
byte[] buff = new byte[1024 * 1024 * 1];
WeakReference<byte[]> s = new WeakReference<>(buff); //弱引用
list.add(s);
}
System.gc(); //触发垃圾回收
for (int i = 0; i < list.size(); i++) {
WeakReference s =(WeakReference)list.get(i);
System.out.println(s.get());
}
}
结果如下
null
null
null
null
null
null
null
null
null
null
对象都被回收了
虚引用
也称为幽灵引用或者幻影引用。本身Phantom就是幽灵,幻影的意思。这时最弱的一种引用。弱到什么程度呢?就是说一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象的实例。它的唯一目的只是为了能够在这个对象被回收时收到一个系统的通知。可以使用PhantomReference来实现虚引用。