WeakReference#get()何时开始返回null?

我想使用WeakReference s作为(android)位图caching的一部分,以便能够检查何时不再使用位图。

我的caching的最大尺寸比Java堆空间小。 当一个新的位图会溢出caching时,它应该放弃不再需要的位图。

我的问题:什么时候WeakReference的get()方法返回null?

  1. 只要没有更强的对象的引用? (并且GC还没有发生)
  2. 或者当GC运行并确定它们没有更强的对象的引用?

如果2.是真的比我可能遇到的情况,我的caching可以填补和GC最近没有运行的原因。

然后,即使我在上次GC运行后已经放弃了引用, WeakReference#get()仍然会返回该对象,并且我的caching不会将其清除。

Solutions Collecting From Web of "WeakReference#get()何时开始返回null?"

答案取决于你使用的Android版本。 在2.3时间的某个地方,Android改变了处理或者弱引用。 以前,它在GC运行时将其删除。 在2.3(2.3.3?)的某个版本中,在最后一个强烈的引用消失后,它立即删除它们。 所以在Android的现代版本中,弱引用是无用的。

在这个变化之前,弱引用被用于caching。 他们不再工作。 现在正确的方法是使用LRUCache。 如果您需要支持旧版本,请使用支持库来回溯LRUcaching。

经过一番search后,我认为这个变化是在3.0而不是2.3。 不过,解决scheme是一样的。

一旦GC确定对象弱到达,WeakReference被清除。

这接近你的第二个案例。 然而,弱可达性不仅需要缺less强参考,而且还缺乏软参考。

从java.lang.ref的Java包文档:

软和弱引用在被添加到它们注册的队列(如果有的话)之前被收集器自动清除。

如果一个对象既不强,也不是轻度可达,但是可以通过遍历一个弱引用来达到。 当对弱可达对象的弱引用被清除时,该对象就有资格完成。

caching位图使用SoftReference而不是Weak。 GC将尽快清除弱引用,只要它丢失了所有可能破坏caching目的的强引用和软引用。 SoftReference只有在内存不足的情况下才会被清除,并保证GC在投掷OOME之前运行。

正如在其他答案中所述,WeakReference将返回null,一旦指向的对象没有更多的强/软引用 GC已回收内存。

根据更一般的规则,我不认为弱/软引用在应用程序中是好事。 它使你的组合担忧:

  • 您的应用程序是关于业务逻辑
  • JVM和Dalvik关于内存pipe理和代码优化。

当你开始使用弱/弱引用时,你在应用程序中引入了内存pipe理的关注点,这使得开发/debugging/理解变得困难。

您可能希望具有固定大小(元素或位图大小的数量)的LRUcaching。

希望有所帮助!