详见以下测试代码及其注释:
package test;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import org.junit.Test;
class VeryBig {
private static final int SIZE = 1000;
private double[] la = new double[SIZE];
private String ident;
public VeryBig(String id) {
ident = id;
}
public VeryBig(String id, int s) {
ident = id;
la = new double[s];
}
public String toString() {
return ident;
}
protected void finalize() {
System.out.println("Finalizing " + ident);
}
}
public class ReferencesTest {
/**
* Strong Reference<br>
* 是 Java 的默认引用实现, 它会尽可能长时间的存活于 JVM 内, 当没有任何强引用指向对象时, GC 执行后将会回收对象
*/
@Test
public void strongReferenceNotGC() {
System.out.println("start test strongReferenceNotGC");
Object referent = new VeryBig("strongReferenceNotGC");
/**
* 通过赋值创建 StrongReference
*/
Object strongReference = referent;
assertSame(referent, strongReference);
referent = null;
System.gc();
/**
* 由于对象还存在引用,因此gc后,对象未被回收
*/
assertNotNull(strongReference);
System.out.println("end test strongReferenceNotGC");
}
@Test
public void strongReferenceGC() throws InterruptedException {
System.out.println("start test strongReferenceGC");
Object referent = new VeryBig("strongReferenceGC");
referent = null;
System.gc();
Thread.sleep(500);
System.out.println("end test strongReferenceGC");
}
/**
* WeakReference<br>
* 顾名思义, 是一个弱引用, 当所引用的对象在 JVM 内不再有强引用时, GC后,弱引用被置成null,并回收所指的对象
*
* @throws InterruptedException
*/
@Test
public void weakReference() throws InterruptedException {
System.out.println("start test weakReference");
WeakReference<Object> weakRerference = new WeakReference<Object>(new VeryBig(
"weakReference"));
System.gc();
Thread.sleep(500);
/**
* weak reference 在 GC 后会被置成null,对象就可以被 回收了。。。
*/
assertNull(weakRerference.get());
System.out.println("end test weakReference");
}
/**
* WeakHashMap<br>
* 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的
* entry
*
* @throws InterruptedException
*/
@Test
public void weakHashMap() throws InterruptedException {
Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>();
Object key = new VeryBig("weakHashMap key");
Object value = new Object();
weakHashMap.put(key, value);
assertTrue(weakHashMap.containsValue(value));
key = null;
System.gc();
/**
* 等待无效 entries 进入 ReferenceQueue 以便下一次调用 getTable 时被清理
*/
Thread.sleep(1000);
/**
* 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry
*/
assertFalse(weakHashMap.containsValue(value));
}
/**
* SoftReference<br>
* 与 WeakReference 的特性基本一致, 最大的区别在于
* SoftReference会尽可能长的保留引用,不会在GC时就回收对象,而是直到 JVM 内存不足时才会被回收(虚拟机保证),
* 这一特性使得 SoftReference 非常适合缓存应用
*/
@Test
public void softReference() {
SoftReference<Object> softRerference = new SoftReference<Object>(new VeryBig(
"softReference"));
assertNotNull(softRerference.get());
System.gc();
/**
* soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用
*/
assertNotNull(softRerference.get());
// make oom....
int i = 0;
while (true) {
try {
++i;
new VeryBig("oom ", 10000000);
} catch (Throwable e) {
System.out.println("OOM after " + i + " times");
e.printStackTrace();
break;
}
}
assertNull(softRerference.get());
}
/**
* PhantomReference<br>
* Phantom Reference(幽灵引用) 与 WeakReference 和 SoftReference 有很大的不同, 因为它的
* get() 方法永远返回 null, 这也正是它名字的由来
*/
@Test
public void phantomReferenceAlwaysNull() {
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(
new VeryBig("phantomReferenceAlwaysNull"), q);
/**
* phantom reference 的 get 方法永远返回 null
*/
assertNull(phantomReference.get());
assertNull(q.poll());
System.gc();
assertNull(q.poll());
}
/**
* RererenceQueue<br>
* 当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收, 这时可以做一些合适的清理工作. 将一个
* ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个weak ref插入到
* ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的
* entries
*
* @throws InterruptedException
*/
@Test
public void referenceQueueWithWeakReference() throws InterruptedException {
Object referent = new VeryBig("referenceQueueWithWeakReference");
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
Reference<Object> ref = new WeakReference<Object>(referent, referenceQueue);
assertFalse(ref.isEnqueued());
Reference<? extends Object> polled = referenceQueue.poll();
assertNull(polled);
referent = null;
System.gc();
assertTrue(ref.isEnqueued());
Reference<? extends Object> removed = referenceQueue.remove();
assertNotNull(removed);
assertSame(ref, removed);
assertNull(removed.get());
}
@Test
public void referenceQueueWithSoftReference() throws InterruptedException {
Object referent = new VeryBig("referenceQueueWithWeakReference");
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
Reference<Object> ref = new SoftReference<Object>(referent, referenceQueue);
assertFalse(ref.isEnqueued());
Reference<? extends Object> polled = referenceQueue.poll();
assertNull(polled);
referent = null;
// make oom....
try {
new VeryBig("oom ", 100000000);
} catch (Throwable e) {
}
assertTrue(ref.isEnqueued());
Reference<? extends Object> removed = referenceQueue.remove();
assertNotNull(removed);
assertSame(ref, removed);
assertNull(removed.get());
}
}
参考:
http://www.iteye.com/topic/401478
http://zhang-xzhi-xjtu.iteye.com/blog/484934
http://zhang-xzhi-xjtu.iteye.com/blog/413159
分享到:
相关推荐
SoftReference、WeakReference和PhantomRefrence分析和比较
StrongReference,SoftReference, WeakReference的使用实例,请参照博客:http://blog.csdn.net/To_be_Designer/article/details/72673421
主要介绍了Java弱引用(WeakReference)的理解与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
3.1 强引 3.2 软引 3.3 弱引 3. 4 假象引
该Demo主要原理: 加载图片时先查看缓存中时候存在该图片,如果存在则返回该图片,否则先加载载一个...并且处理的多个细节,包括使用WeakReference、SoftReference防止内存溢出、解决使用Handler时context泄露问题 登
本篇文章尝试从What、Why、How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义、基本使用场景和使用方法。由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出,谢谢大家:) 1....
这个项目为万能的(有时是可怕的)弱引用实现了一个kotlin包装器,以便您可以更友好地使用它们。
这是对 java.lang.ref.WeakReference 实现的修改,它将通过 JMX MBean 跟踪和报告它发现的内容。如何使用: 在您的应用程序中启用 JMX。 然后使用指向此实现的引导类路径启动 Java 应用程序。 例如: $ java -...
【Mybatis】MyBatis中使用#和$书写占位符有什么区别? 100 【Mybatis】Mybatis是如何进行分页的?分页插件的原理是什么? 100 【数据库】什么是事务?事务的四个特性?事务的隔离级别?什么是脏读,不可重复读,幻读...
ava有四种引用类型,strongreference,softreference,weakreference,phantomreference。本篇文档主要的就是进阶的介绍和了解这四种引用类型的异同点,助于你对java的更好的学习理解
1.强引用1.强引用 2.软引用(SoftReference) 3.弱引用(WeakReference) 4.虚引用(PhantomReference) 等等;
.NET中提供了WeakReference来实现。弱引用可以让您保持对对象的引用,同时允许GC在必要时释放对象,回收内存。对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望GC必要...
AsyncTask_WeakReference
很早Java API就添加了弱引用(WeakReference)和软引用(SoftReference),但并不是所有的程序员都熟悉这两个概念
Java中要用到缓存的地方很多,首当其冲的就是持久层缓存,针对持久层谈一下: 要实现java缓存有很多种方式,最简单的无非就是static HashMap,这个显然是基于内存缓存,一个map就可以搞定引用对象的缓存,最简单也...
java8 源码 GH-Demo 1、jOOR源码研习,并优化对Class、Field等的缓存 2、模仿Glide在View中监听Activity的生命周期 3、整理日志规范及方案记录 ...11、学习LeadkCanary中对内存泄漏的检测方法--WeakReference
├─Google Guava 第14讲-Guava之Closer使用和原理剖析,非常重要.wmv ├─Google Guava 第15讲-Base64原理详解,手动实现base64的Encoding.wmv ├─Google Guava 第16讲-Base64原理详解,手动实现base64的...
创建用于WPF MVVM绑定的Singleton,并对绑定的属性使用弱引用的概念。
常见的面试中会有这么一道题,“谈谈强引用、 软引用、 弱引用、虚引用”。 A:强引用,通过new出来的都是强引用 Q:那弱引用呢? A:通过WeakReference构造出的,不再有强引用… Q:那软引用呢,这些...