我读过这篇关于Java中不同类型引用(强、软、弱、幻影)的文章,但我不是很理解。
这些引用类型之间的区别是什么,什么时候使用每种类型?
我读过这篇关于Java中不同类型引用(强、软、弱、幻影)的文章,但我不是很理解。
这些引用类型之间的区别是什么,什么时候使用每种类型?
当前回答
弱参考:
简单地说,弱引用是指没有强到足以迫使对象保留在内存中的引用。弱引用允许您利用垃圾收集器的能力来确定您的可达性,因此您不必自己做这件事。
软参考:
软引用与弱引用完全相似,只是它不太急于丢弃所引用的对象。只有弱可及性的对象(对它的最强引用是WeakReferences)将在下一个垃圾收集周期中被丢弃,但软可及性的对象通常会保留一段时间。
幻影参考:
虚引用与软引用或弱引用是完全不同的。它对对象的控制是如此脆弱,以至于您甚至无法检索对象——它的get()方法总是返回null。这种引用的唯一用途是跟踪它何时进入ReferenceQueue队列,因为在这一点上,您知道它所指向的对象已经死亡。
本文摘自:https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
其他回答
软参考和弱参考之间的简单区别是由Android开发者提供的。
软引用和弱引用之间的区别是决定清除引用并将其排队的时间点:
一个SoftReference应该被清除并尽可能晚地进入队列, 即防止虚拟机存在内存不足的危险。 WeakReference可以在已知的情况下被清除并加入队列 weakly-referenced。
4个参照度-强,弱,软,幻影
强-是一种引用,它使被引用的对象不 有资格获得GC。构建器类。StringBuilder Weak -是一个符合GC条件的引用。 Soft -是一种引用,其对象在内存可用之前都有资格进行GC。最适合图像缓存。它将保存它们,直到内存可用为止。 幻影——是一种引用,其对象直接适合GC。仅用于了解对象何时从内存中删除。
用途:
允许您识别对象何时从内存中完全删除。 当finalize()方法重载时,对于两个类中符合GC条件的对象可能不会及时进行GC。因此,幻影引用使它们有资格在finalize()之前进行GC,这就是为什么即使堆的大部分是垃圾,您也可以获得OutOfMemoryErrors。
弱引用是实现缓存模块的理想方法。
强引用
这些是我们每天编写的常规对象引用:
Employee emp = new Employee();
变量“emp”保存着对Employee对象的强引用,通过任何强引用链可访问的对象都不符合垃圾收集的条件。 通常,这是你想要的,但并不总是如此。现在假设我们在一个集合或映射中从数据库中获取大量的员工,我们需要定期对他们进行大量的处理,所以为了保持性能,我们将他们保存在缓存中。
到目前为止,这很好,但现在我们需要不同的数据,我们不需要那些Employee对象,这些不从任何地方引用,除了缓存。这导致了内存泄漏,因为这些对象没有被使用,但仍然不符合垃圾收集的条件,我们不能从缓存中删除这些对象,因为我们没有对它们的引用? 所以在这里,我们要么需要手动清空整个缓存,这很乏味,要么我们可以使用其他类型的引用,例如弱引用。
弱引用
弱引用不会将对象固定到内存中,如果没有从其他引用引用,则会在下一个GC循环中进行GC。我们可以使用Java提供的WeakReference类来创建上述类型的缓存,它不会存储没有从其他地方引用的对象。
WeakReference<Cache> cache = new WeakReference<Cache>(data);
要访问数据,需要调用cache.get()。如果弱引用被垃圾回收,这个get调用可能返回null:你必须检查返回值以避免npe。 Java提供了使用弱引用的集合,例如WeakHashMap类将键(而不是值)存储为弱引用。如果键被GC化了,那么该值也会自动从映射中删除。
由于弱引用也是对象,我们需要一种方法来清理它们(当它们引用的对象已经被GC化时,它们就不再有用了)。如果您将ReferenceQueue传递给弱引用的构造函数,那么垃圾收集器将在ReferenceQueue最终确定或GC - d之前将该弱引用附加到ReferenceQueue。您可以定期处理这个队列并处理死引用。
软引用
软引用类似于弱引用,但它不太可能被垃圾收集。垃圾收集器根据内存需求自行清除软引用。虚拟机保证在抛出OutOfMemoryError错误之前,对软可达对象的所有软引用都将被清除。
幽灵的引用
幻影引用是所有引用类型中最弱的,对它们调用get总是返回null。一个对象在它被终结后,但在它分配的内存被回收之前被幻影引用,与弱引用相反,弱引用在它们被终结之前被排队,或者很少使用幽灵引用。
那么它们有什么用处呢?当你构造一个虚引用时,你必须传递一个referencqueuue。这表明您可以使用幻影引用来查看对象何时被GC。
Hey, so if weak references are enqueued when they’re considered finalize but not yet GC’d we could create a new strong reference to the object in the finalizer block and prevent the object being GC’d. Yep, you can but you probably shouldn’t do this. To check for this case the GC cycle will happen at least twice for each object unless that object is reachable only by a phantom reference. This is why you can run out of heap even when your memory contains plenty of garbage. Phantom references can prevent this.
你可以阅读我的文章《Java中的引用类型(强,软,弱,幻影)》。
弱参考:
简单地说,弱引用是指没有强到足以迫使对象保留在内存中的引用。弱引用允许您利用垃圾收集器的能力来确定您的可达性,因此您不必自己做这件事。
软参考:
软引用与弱引用完全相似,只是它不太急于丢弃所引用的对象。只有弱可及性的对象(对它的最强引用是WeakReferences)将在下一个垃圾收集周期中被丢弃,但软可及性的对象通常会保留一段时间。
幻影参考:
虚引用与软引用或弱引用是完全不同的。它对对象的控制是如此脆弱,以至于您甚至无法检索对象——它的get()方法总是返回null。这种引用的唯一用途是跟踪它何时进入ReferenceQueue队列,因为在这一点上,您知道它所指向的对象已经死亡。
本文摘自:https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Java提供了两种不同类型/类的引用对象:强和弱。弱引用对象可以进一步分为软引用对象和虚引用对象。
强大的 弱 软 幻影
让我们逐点分析。
强引用对象
StringBuilder builder = new StringBuilder();
这是默认类型/类的引用对象,如果没有不同的指定:builder是一个强引用对象。这种引用使得被引用的对象不适合GC。也就是说,当一个对象被一串强引用对象引用时,它就不能被垃圾收集。
弱引用对象
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Weak Reference Objects are not the default type/class of Reference Object and to be used they should be explicitly specified like in the above example. This kind of reference makes the reference object eligible for GC. That is, in case the only reference reachable for the StringBuilder object in memory is, actually, the weak reference, then the GC is allowed to garbage collect the StringBuilder object. When an object in memory is reachable only by Weak Reference Objects, it becomes automatically eligible for GC.
弱点的程度
有两种不同程度的弱点:软的和幻影的。
软引用对象基本上是一个弱引用对象,它在内存中保留的时间更长一些:通常,它会抵抗GC循环,直到没有可用内存,并且存在OutOfMemoryError的风险(在这种情况下,可以将其删除)。
另一方面,虚引用对象仅在确切地知道对象何时已从内存中有效移除时有用:通常它们用于修复奇怪的finalize()复活/复活行为,因为它们实际上不返回对象本身,而只是帮助跟踪它们在内存中的存在。
弱引用对象是实现缓存模块的理想对象。事实上,当强引用链不再访问对象/值时,可以允许GC清理内存区域,从而实现一种自动清除。一个例子是保留弱键的WeakHashMap。