我想使用WeakReference
s作为(android)位图缓存的一部分,以便能够检查何时不再使用位图。
我的缓存的最大大小小于Java堆空间。当一个新的位图溢出缓存时,它应该放弃不再需要的位图。
我的问题:WeakReference
的get() - 方法什么时候返回null?
如果2.为真,那么我可能遇到我的缓存可能会填满并且GC最近因某些原因没有运行的情况。
然后,即使我在上一次GC运行后已经放弃了引用,WeakReference#get()
仍会返回该对象,我的缓存也不会清除它。
答案 0 :(得分:10)
答案取决于您使用的Android版本。在2.3时间框架的某个地方,Android改变了它的处理或弱引用。以前,它在GC运行时删除了它们。从某些版本的2.3(2.3.3?)开始,它会在最后一次强引用后立即删除它们。所以在Android的现代版本中,弱引用是无用的。
在此更改之前,弱引用用于缓存。他们不再工作了。现在正确的方法是使用LRUCache。如果需要支持旧版本,请使用支持库来反向移植LRU缓存。
经过一番搜索,我认为改变是在3.0而不是2.3。不过,解决方案是一样的。
答案 1 :(得分:5)
一旦GC确定对象无法到达,就会清除WeakReference。
这接近你的第二个案例。然而,弱可达性不仅需要缺少强引用,还需要缺少软引用。
来自java.lang.ref的Java包文档:
收集器会自动清除软引用和弱引用,然后将其添加到注册它们的队列(如果有)。
...
如果某个对象既不强也不可轻松到达,则可以通过遍历弱引用来访问该对象。当清除对弱可达对象的弱引用时,该对象就有资格进行最终确定。
答案 2 :(得分:4)
要缓存位图,请使用SoftReference而不是Weak。一旦失去所有可能破坏缓存目的的强引用和软引用,GC就会清除WeakReference。只有在内存不足时才会清除SoftReference。并保证在投掷OOME之前运行GC。
答案 3 :(得分:-3)
如其他答案中所述,一旦指向对象没有更多强/软引用和 GC已回收内存,WeakReference将返回null。
在更一般的规则上,我认为Weak / SoftReferences在应用程序中不是一件好事。它会引起你的混合问题:
当您开始使用弱/软引用时,您会在应用程序中引入内存管理的问题,这使得开发/调试/理解变得更加困难。
您可能希望使用固定大小(元素数或位图大小)LRU缓存。
希望有所帮助!