ref: http://blog.csdn.net/rocksword/article/details/43033465
写这篇文章的目的,其实是因为之前就有听过这东西,再加上去练习面试被问到这一题 Orz 答的很烂…
所以就下定决心一定要开始搞懂自己听过,但不是很懂的东西...
这几个 Reference,引用的强度由大至小,是 StrongReference > SoftReference > WeakReference
所以我们先大约了解,当我们用 Java 宣告一个变量的时候,在内存中发生了什麽事:
People pp = new People();
首先局部变量 pp 会在 stack中产生,然後存有一个地址,用来指向 heap中 People的数据,如下图:
这种指向关系,就称为「强引用 - StrongReference」在 JAVA 垃圾回收的机制中,如果有强引用指向任一在 heap中的对象,
则 JVM便不会将这个对象回收,只有在没有强引用的情况下,才会将此对象回收,StrongReference 是 Java
的默认引用实现。
软引用( SoftReference ) 则是在 JVM内存快不足时,在没有其它引用的情况下, 垃圾回收机制会将此对象回收。如下图
而弱引用(WeakReference),便是一旦该变量不再使用,并且没其它引用时,便直接回收该对象
范例代码如下:
public class testMain {
public static void main(String[] args) {
// StrongReference trongReference 是 Java 的默认引用实现,
// 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收
RefTest obj = new RefTest(RefTest.STRONG_REF);
Object strongRef = obj; //将强引用指向 obj 所指向的 heap对象
obj = null; //将原本的强引用指向null
System.gc(); //执行垃圾回收
System.out.print("StrongReference: ");
checkIfNull(strongRef);
// WeakReference,当不再有其它引用 GC後将被自动回收。
RefTest obj2 = new RefTest(RefTest.WEAK_REF);
WeakReference<Object> weakRef = new WeakReference<Object>(obj2);
obj2 = null;
System.gc();
System.out.print("WeakReference: ");
checkIfNull(weakRef.get());
// SoftReference
RefTest obj3 = new RefTest(RefTest.SOFT_REF);
SoftReference<Object> softRef = new SoftReference<Object>(obj3);
obj3 = null;
System.gc();
System.out.print("SoftReference: ");
checkIfNull(softRef.get());
// 试著使 JVM内存不足
ArrayList<RefTest> list = new ArrayList<RefTest>();
for (;;) {
list.add(new RefTest(RefTest.SOFT_REF));
if (softRef.get() == null) {
System.out.println("jvm is almost out of memory, recycle SoftReference");
break;
}
}
}
// 看看是 heap中的对象是否已被回收
private static void checkIfNull(Object obj) {
if (obj == null) {
System.out.println("obj == null");
} else {
System.out.println("obj != null");
}
}
// 测试对象
private static class RefTest extends Object {
private long[] mData;
private int mRefType;
public static final int STRONG_REF = 1;
public static final int WEAK_REF = 2;
public static final int SOFT_REF = 3;
public RefTest(int refType) {
mData = new long[100];
mRefType = refType;
}
protected void finalize() {
if (mRefType == STRONG_REF) {
System.out.print("StrongReference: ");
} else if (mRefType == WEAK_REF) {
System.out.print("WeakReference: ");
}
System.out.println("Object is being recycled");
}
}
}
输出:
以上~ 如果理解有错误,请多多指教~