weakreference使用,weak function

http://www.itjxue.com  2023-01-20 09:16  来源:未知  点击次数: 

理解StrongReference,SoftReference, WeakReference的区别

Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (传说中的幽灵引用 呵呵),

这 4 种类型的引用与 GC 有着密切的关系,? 让我们逐一来看它们的定义和使用场景 :

1. Strong Reference

StrongReference 是 Java 的默认引用实现,? 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收

@Test?

public void strongReference() {?

Object referent =new Object();?

/**

? * 通过赋值创建 StrongReference

? ? */?

? ? Object strongReference = referent;?

? assertSame(referent, strongReference);?

referent =null;?

System.gc();?

/**

? ? * StrongReference 在 GC 后不会被回收,因为StrongReference 是用= ,强引用,如果再把strongReference=null 那将回收

? ? */?

assertNotNull(strongReference);?

}?

? 2. WeakReference WeakHashMap

WeakReference, 顾名思义,? 是一个弱引用,? 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收

@Test?

public void weakReference() {?

Object referent =new Object();?

WeakReference weakRerference =new WeakReferenceObject(referent);?

assertSame(referent, weakRerference.get());?

referent =null;?

System.gc();?

/**

? ? * 一旦没有指向 referent 的强引用, weak reference 在 GC 后会被自动回收

? ? */?

assertNull(weakRerference.get());?

}?

WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry

@Test?

public void weakHashMap() throws InterruptedException {?

Map weakHashMap =new WeakHashMapObject, Object();?

Object key =new Object();?

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));?

}?

3. SoftReference

SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用

@Test?

public void softReference() {?

Object referent =new Object();?

SoftReference softRerference =new SoftReferenceObject(referent);?

? ? assertNotNull(softRerference.get());?

referent =null;?

? ? System.gc();?

/**

? ? *? soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用

? ? */?

? ? assertNotNull(softRerference.get());?

}?

C#弱引用(WeakReference)

在日常开发中,通常会遇到一些大对象的处理。这些大对象通常在整个程序中多次使用。例如:大文件对象,大的字典类。通常情况下我们会使用下面的方式:

作为一个方法的内置本地变量;

作为一个类的字段存在;

这两种方式都不是很好。作为一个类的字段,类的实例将一直持有这个大对象,消耗很多内存;作为一个方法的本地变量使用,当方法执行完毕,这个大对象离开了作用域,但此时不一定会被GC直接回收。造成不必要的内存消耗。且每次调用该方法时,会重新创建新的大对象,增加程序的内存消耗。

如果创建对象很消耗资源,且我们想要避免多次创建同一个对象。可以使用类的字段方式。

通常情况下,当一个对象离开了作用域,或者被设置为null。我们将无法访问到它。.NET提供了一个 WeakReference 类,可以完美的解决这个问题。

引用:

[.NET] WeakReference的使用

WeakReference

A SoftReference should be cleared and enqueued as late as possible, that is, in case the VM is in danger of running out of memory.

一个软引用应该尽可能迟的被清理和入列,因此,在这种情况下虚拟机(VM)就存在内存溢出的风险(危险)。

个人理解:问题在“as late as possible”——始终过迟的清理垃圾,肯定就有内存溢出的风险(危险)。

------------------------------------

All objects formerly being referenced by ref become eligible for finalization.

所有先前被ref引用的对象都将符合垃圾回收(finalization)的条件。

ref:地址引用,java里就是指被new创建的对象。

除非是使用JNI,所占用的内存将不在ref的范围(Thinking in Java 4th, 120页)

何时该用WeakReference

何时该用WeakReference

答:一个例子是:当你的图片Bitmap生成通过AsynchTask 做好回来,需要用到ListView里的ImageView,而此ImageView有可能因为滚动的缘故不存在的话,针对这种情况,就要对ImageView来适用WeakReference, 适用动作在AsynchTask创建时就用WeakReference来引用ImageView 对象。

例子可见Android manual.

简单原则:对要用的对象,没有绝对控制权,需要小心使用WeakReference,确保此对象是存在的。

(责任编辑:IT教学网)

更多

推荐数据库文章