弱参考和软参考

时间:2015-09-07 17:41:27

标签: java weak-references soft-references

弱引用允许GC在下一个GC循环中收集引用,而Soft Reference将保留引用直到内存已满并且在丢失内存错误之前,它将删除软引用。 我们将在哪里使用这些参考? 哪个参考最适合实现缓存? 例如:如果我使用软引用进行缓存,那么当内存已满时它将被清除。 但是我们假设,我已经获取了一些数据库详细信息并将其放入内存并在软引用中缓存了该细节,现在如果我从内存中删除了一些键值,它仍然会在缓存中。我们需要在此使用弱引用案例?如何做出决定。

4 个答案:

答案 0 :(得分:1)

在大多数情况下,Soft References用于缓存。您希望尽可能长时间地将数据保存在RAM中,但最好使用OOM清除缓存而不是死亡。

可以使用弱引用(例如)来保留关于您的类的额外信息。你有一个类User并且你想要存储一些额外的信息,这些信息应该在删除用户时删除(你不想手动操作,因为它是bolierplate代码)。因此,您使用WeakHashMap作为键使用User,当没有对用户的引用时,也会从此地图中删除它。

顺便说一句:在引用计数弱的引用的语言中,用于防止引用循环,但是java GC会删除隔离区域,因此弱引用的使用不适用于java。

答案 1 :(得分:0)

如果要实现自己的缓存,请使用Soft Reference。

我曾经维护过遗留系统,该系统使用弱引用缓存来存储创建成本非常高的大对象。几乎每次线程都试图从该缓存中获取一个对象时,它就已经被GC控制了,因此必须对这些对象进行大量的重建!它实际上就像缓存不存在一样。

  

但是让我们假设,我已经获取了一些数据库细节并将其放入内存中并在软引用中缓存了该细节,现在如果我从内存中删除了一些键值,它仍将存在于缓存中。在这种情况下我们是否需要使用弱引用?如何做出决定。

我不确定我理解你的问题。当对这些细节的原始“硬”引用是GC时,它仍然可以在软引用的缓存中。如果您从缓存中删除该项目,则根本不再有对详细信息的引用,因此无论何时使用哪种引用指向它都将进行GC。

WeakReference很有用。有关示例,请参阅Weak references - how useful are they?

答案 2 :(得分:0)

  

哪种参考最适合实施缓存?

对于缓存使用SoftReference类,缓存事物的全部目的是为了快速使用它 - 如果内存可用。因此,当内存很少时,可以刷新缓存。

WeakReference非常适合避免引用泄漏,当你有一些静态对象或线程来保持对生命周期比这个对象/线程更短的对象的引用时,就会发生这种情况。我在android开发中使用了很多WeakReference - s,尤其是AsyncTask,它的生命周期通常比创建它们的Activity-s生命周期长。

  

......在这种情况下我们是否需要使用弱引用?

一旦从缓存集合中删除此类条目,它将被垃圾收集,因此不需要WeakReference。

我从未使用过SoftReferences - 但那是因为我主要在android平台下编码,根据其文档http://developer.android.com/reference/java/lang/ref/SoftReference.html,它们对于缓存没用 - 至少在这个平台下。

答案 3 :(得分:0)

  

弱引用允许GC在下一个GC循环中收集引用,而Soft Reference将保留引用直到内存已满并且在丢失内存错误之前,它将删除软引用。

您正在阅读的文档比他们实际说的更多。在VM抛出OutOfMemoryError之前,将清除并释放所有可轻松访问的对象(这使得它们无法被强制访问),但是在最初确定VM时,VM绝不需要保留它们。可以轻松到达。文档并不禁止它们在相同的GC循环中被回收,在这个循环中它们被轻易地到达。

但是,一般来说,您可以假设GC首选处理幻像可达和弱可达对象。

  

我们将使用这些参考资料?哪个参考最适合实现缓存?

The docs这样说:

  

软引用用于实现对内存敏感的缓存,弱引用用于实现规范化映射,这些映射不会阻止其键(或值)被回收,而虚拟引用用于以更灵活的方式调度预先清理操作比Java完成机制可能的那样。

你继续问:

  

例如:如果我使用软引用进行缓存,那么当内存已满时它将被清除。但是我们假设,我已经获取了一些数据库详细信息并将其放入内存并在软引用中缓存了该细节,现在如果我从内存中删除了一些键值,它仍然会在缓存中。我们需要在此使用弱引用案例?如何做出决定。

如果要构建一个可以丢弃其密钥不再可以访问的条目的缓存(这可能意味着无法再检索这些条目),那么这就完全位于弱参考的预期目的。缓存内部仅保存对每个条目的键的弱引用,并使用ReferenceQueue注册这些引用,以便知道何时应该丢弃它们。这正是WeakHashMap的工作原理。

如果你想构建一个可以通过丢弃条目来响应高内存需求的缓存,那么这就是软引用(对于值)的预期目的;这样的缓存与WeakHashMap的工作方式类似,但使用对的软引用,而不是对密钥的弱引用。当然,这两者可以结合起来。

顺便说一下,注意Reference个对象只有在它们的指示对象强烈无法访问时才与GC相关。特别是,对一个对象SoftReference本身并不保证该对象将被回收,无论对内存的需求是什么。没有强烈可达的对象永远有资格进行最终确定或回收。

相关问题