强引用
/*
* 这样普通的列出来就是强引用
*/
Object obj = new Object();
软引用
Object obj1 = new Object();
/*
* 软引用
* 用来实现一些内存敏感的缓存(Soft references are for
* implementing memory-sensitive caches),只要内存
* 空间足够,对象就会保持不被回收.
*
* 当宿主进程的内存空间不足时,对象就会被GC回收。
*/
ReferenceQueue<Object> queueSoft = new ReferenceQueue<>();
SoftReference<Object> softReference = new SoftReference<>(obj1, queueSoft);
弱引用
Object obj2 = new Object();
/*
* 弱引用
*
* WeakReference可以用来实现一些规范化映射(WeakHashMap),其
* 中key或者value当它们不再被引用时
* 可以自动被回收.
* 当你想引用一个对象,但是这个对象有自己的生命周期,你不想介入这个
* 对象的生命周期这时候就可以使用弱引用.
* 这个引用不会在对象的垃圾回收判断中产生任何附加的影响.
*/
ReferenceQueue<Object> queueWeak = new ReferenceQueue<>();
WeakReference<Object> weakReference = new WeakReference<>(obj2, queueWeak);
虚引用
这个虚引用用到了我自定义的一个Object类。
public class TestOject extends Object {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("method finalize() execute");
}
}
下面是具体的虚引用记录。
Object obj3 = new TestOject();
/*
* 虚引用
* PlantomReference和WeakReference一样,也不会介入引用对象的生命周期.
* PlantomReference比较特殊,它的get方法总是返回null,所以你得不到它引
* 用的对象.
*
* 虚引用主要是用来跟踪对象被垃圾回收的状态,通过查看引用队列中是否包含对
* 象对应的虚引用来判断它是否即将被垃圾回收。
*
* 很重要的一点:虚引用不会根据内存情况自动回收目标对象!!
* 因此虚引用可能发生内存泄露的情况!!!
*/
ReferenceQueue<Object> queuePlantom = new ReferenceQueue<>();
PhantomReference<Object> phantomReference =
new PhantomReference<>(obj3, queuePlantom);
log("normal obj3: " + obj3);
log("phantom reference: " + phantomReference);
log("phantom reference method get(): " + phantomReference.get());
log("reference queue method poll(): " + queuePlantom.poll());
log("phantom reference is enqueued? : " + phantomReference.isEnqueued());
obj3 = null;
/*
* 这里只是建议java虚拟机去执行gc
*/
System.gc();
log("first gc....");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log("phantom reference method get(): " + phantomReference.get());
Reference<?> poll = queuePlantom.poll();
log("reference queue method poll(): " + poll);
log("phantom reference is enqueued? : " + phantomReference.isEnqueued());
/*
* 这里再次建议建议java虚拟机去执行gc
*/
System.gc();
/*
* 这个方法时建议java虚拟机去执行有些对象中的finalize()方法。前
* 提是这个对象中的finalize方法没有被执行过。
*/
//System.runFinalization();
log("second gc....");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*
* 当系统执行过gc后obj3并没有立即被回收,系统而是将phantomReference插
* 入到queuePlantom这个队列中。
* 当再次调用queuePlantom.poll()方法时返回phantomReference对象。poll
* 方法会先把phantomReference的
* 持有队列queue(ReferenceQueue<? super T>)置为NULL,NULL对象继承
* 自ReferenceQueue,
* NULL对象的enqueue(Reference paramReference)方法一直返回return false。
*
* 注意将phantomReference插入到queuePlantom这个队列中的操作的时间是不受
* 我们控制的,由java虚拟机控制。
*
* 我们判断obj3是否被垃圾回收就应该判断queuePlantom.poll()返回的对象引
* 用是否为obj3。
*/
log("reference queue method poll(): " + queuePlantom.poll());
log("phantom reference is enqueued? : " + phantomReference.isEnqueued());
printInfo(phantomReference);
/*
* 要手动调用clear()方法来清除包含的引用
*/
phantomReference.clear();
printInfo(phantomReference);
下面是虚引用相关的log输出。
normal obj3: org.tuzhao.reference.TestOject@330bedb4
phantom reference: java.lang.ref.PhantomReference@2503dbd3
phantom reference method get(): null
reference queue method poll(): null
phantom reference is enqueued? : false
first gc....
method finalize() execute
phantom reference method get(): null
reference queue method poll(): null
phantom reference is enqueued? : false
second gc....
reference queue method poll(): java.lang.ref.PhantomReference@2503dbd3
phantom reference is enqueued? : false
print info start
filed : referent value: org.tuzhao.reference.TestOject@330bedb4
filed : queue value: java.lang.ref.ReferenceQueue$Null@7ea987ac
filed : next value: java.lang.ref.PhantomReference@2503dbd3
filed : discovered value: null
filed : lock value: java.lang.ref.Reference$Lock@29453f44
filed : pending value: null
print info end
print info start
filed : referent value: null
filed : queue value: java.lang.ref.ReferenceQueue$Null@7ea987ac
filed : next value: java.lang.ref.PhantomReference@2503dbd3
filed : discovered value: null
filed : lock value: java.lang.ref.Reference$Lock@29453f44
filed : pending value: null
print info end
Process finished with exit code 0
本文由 tuzhao 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/02/26 22:15