我读过this article关于Java语言中不同类型的引用(强,软,弱,幻影),但我并不是真的理解它。
这些引用类型之间有什么区别,什么时候会使用每种类型?
发布于 2014-05-07 21:50:30
Java提供了两种不同类型/类的引用对象:强和弱。弱参照对象又可进一步分为软参照对象和幻影参照对象。
让我们一点一点地来。
强引用对象
StringBuilder builder = new StringBuilder();
这是引用对象的默认类型/类,如果没有指定的话:builder
是一个强引用对象。这种引用使得被引用的对象不符合GC的条件。也就是说,每当一个对象被一系列强引用对象引用时,它就不能被垃圾回收。
弱引用对象
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
弱引用对象不是引用对象的默认类型/类,要使用它们,应该像上面的示例中那样显式指定它们。这种引用使引用对象符合GC的条件。也就是说,如果内存中StringBuilder
对象的唯一可达引用实际上是弱引用,则允许GC对StringBuilder
对象进行垃圾回收。当内存中的对象只能由弱引用对象访问时,它将自动成为GC的合格对象。
级别的弱点
可以使用两种不同级别的弱点:软性和幻影。
软引用对象基本上是保留在内存中的弱引用对象:通常,它拒绝GC周期,直到没有内存可用,并且存在OutOfMemoryError
的风险(在这种情况下,它可以被删除)。
另一方面,幻影引用对象只有在确切地知道对象何时被有效地从内存中删除时才有用:通常它们用于修复奇怪的finalize()恢复/复活行为,因为它们实际上不返回对象本身,而只是帮助in keeping track of their memory presence。
弱引用对象是实现缓存模块的理想选择。实际上,只要对象/值不能再通过强引用链访问,就可以通过允许GC清理内存区域来实现一种自动逐出。保留弱密钥的WeakHashMap就是一个例子。
发布于 2012-04-08 20:01:29
Android Developer提供了SoftReference
和WeakReference
之间的简单区别。
SoftReference
和WeakReference
之间的区别在于决定清除引用并将其入队的时间点:
SoftReference
并将其排入队列,以防VM面临内存不足的危险。只要已知为weakly-referenced.,即可清除
WeakReference
并将其入队发布于 2018-12-15 13:16:33
这个article对理解强、软、弱和虚构的引用非常有帮助。
给你一个总结,
如果你有一个对象的强引用,那么这个对象永远不能被GC (垃圾收集器)回收/回收。
如果你只有一个对象的弱引用(没有强引用),那么这个对象将在下一个GC周期中被GC回收。
如果你只有一个对象的软引用(没有强引用),那么这个对象只有在内存耗尽时才会被GC回收。
我们创建对对象的幻影引用,以跟踪对象何时进入ReferenceQueue
队列。一旦你知道了,你就可以执行细粒度的终结化了。(这将使您避免意外地将对象复活为幻影-引用不会给您引用)。我建议您阅读this的文章来深入了解这一点。
所以你可以说,强引用具有终极力量(GC永远不会收集)
软引用比弱引用更强大(因为它们可以逃脱GC周期,直到JVM耗尽内存)
弱引用甚至不如软引用强大(因为它们无法逃脱任何GC周期,并且如果对象没有其他强引用,它们将被回收)。
餐厅类比
新客户- heap
中使用餐桌的新对象
现在,如果你是一个强大的顾客(类似于强引用),那么即使餐馆里来了一个新顾客,你也永远不会离开你的表(堆上的内存区)。服务员没有权利告诉你(甚至没有权利要求你离开餐厅)。
如果你是一个软顾客(类似于软引用),那么如果有新顾客进入餐厅,服务员不会要求你离开桌子,除非没有其他空桌子来容纳新顾客。(换句话说,只有当一位新顾客进来,没有其他桌子留给这个新顾客时,服务员才会要求你离开桌子)
如果你是一个虚弱的顾客(类似于虚弱的推荐人),那么服务员可以(在任何时候)随意要求你离开餐厅:
https://stackoverflow.com/questions/9809074
复制相似问题