我正在阅读WeakReference
和SoftReference
。
找到以下内容:
的WeakReference:
Counter counter = new Counter(); // strong reference - line 1
WeakReference<Counter> weakCounter = new WeakReference<Counter>(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection
软参考:
Counter prime = new Counter(); // prime holds a strong reference - line 2
SoftReference<Counter> soft = new SoftReference<Counter>(prime) ; //soft reference variable has SoftReference to Counter Object created at line 2
prime = null; // now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory
在这里,无论如何,我将 null 分配给强引用计数器和 prime ,它们有资格进行垃圾回收并将被垃圾回收当下一个GC循环运行时。
WeakReference
/ SoftReference
如何影响/协助垃圾收集?
更新
在以下程序中:
public class WeakReferenceSample {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
WeakReference<HelloWorld> helloWorldReference = new WeakReference<>(helloWorld);
helloWorld = null;
System.out.println(helloWorld);
System.out.println(helloWorldReference.get());
System.gc();
System.out.println(helloWorldReference.get());
}
}
即使将helloWorld
引用更改为null
,我的第一个System.out.println(helloWorldReference.get());
也会打印对象值,而不是null
。在System.gc()
之后,第二次打印为null
。由于helloWorld
引用和helloWorldReference
引用都指向同一个HelloWorld
对象,因此内部如何工作。
示例输出:
null
HelloWorld@2503dbd3
null
证明:如果我没有将null
分配给helloWorld
引用,那么helloWorld
引用和helloWorldReference
引用都指向同一个HelloWorld
对象
HelloWorld@2503dbd3
HelloWorld@2503dbd3
HelloWorld@2503dbd3
对内部如何运作感到困惑?之前我曾想过克隆对象然后弱引用它,但是从输出中看,它看起来不像。
答案 0 :(得分:2)
长话短说
没有任何对象具有强引用,因此对象符合垃圾回收的条件。但是不同的引用类型将决定垃圾收集器如何优先处理对象&#39;垃圾收集。
垃圾收集周期中发生的事情的实际细节可能因不同参数而异。 其中一些参数如下:
原则上,垃圾收集器试图快速有效,以免影响长期和短期运行的性能,同时确保有足够的可用内存。
因此在垃圾收集期间,垃圾收集器将尝试通过垃圾收集一些对象来释放一些内存。 垃圾收集器最终将确定它将释放多少内存以及为了执行垃圾收集哪些对象。垃圾收集器不一定在每次运行时垃圾收集所有符合条件的对象。
所以我们可以说有资格进行垃圾收集的对象将被垃圾收集到不同的优先级。因此垃圾收集优先级如下:
基于此优先级,具有弱引用的对象可能比软引用对象更急切地收集垃圾。但是,每个对象何时被垃圾收集的决定和责任仅由垃圾收集器进行。
这个定义讲的是优先级(渴望)而不是精确的规则,所以人们可以期望观察到: 从长远来看(如果在许多不同的JRE和不同情况下观察到),弱引用对象往往会在Soft Referenced对象之前被垃圾收集。
&#34;软引用与弱引用完全相同,只是它不太愿意丢弃它引用的对象。&#34;引用这个答案在这里; Soft vs Weak reference Java还包括Phantom引用,这是一个相关的概念。 Phantom References
在问题更新后更新:
在您的第一个示例中:
null
这是预期的,因为它是helloWorld变量中的强引用,已明确设置为null。
HelloWorld@2503dbd3
helloWorldReference变量中的弱引用尚未被垃圾收集,因此它仍然存在。但是,由于这是对象的唯一引用,因此它有资格进行垃圾回收。如果您多次运行此示例,则可能会打印为null。如果你运行另一个消耗太多内存的线程,你可以看到它。
null
helloWorldReference变量中的弱引用已被垃圾收集。也可能是这个对象不为null,具体取决于运行的垃圾收集器。其中垃圾收集器可以依赖于VM和启动之前给出VM的参数。另请参见System.gc的javadoc。
调用gc方法建议认为Java虚拟机需要花费大量资源来回收未使用的对象,以使其当前占用的内存可用于快速重用。当控制从方法调用返回时,Java虚拟机已经做了尽力而为来从所有丢弃的对象中回收空间。
注意粗体字。他们暗示这个方法并不总是有相同的结果。调用此方法是对VM的建议,该建议将尽最大努力。
在您的第二个示例中:
HelloWorld@2503dbd3
存在helloWorld变量中的强引用
HelloWorld@2503dbd3
helloWorldReference变量中的弱引用尚未被垃圾收集,因为已经存在对此对象的强引用。该对象不符合垃圾回收的条件。
HelloWorld@2503dbd3
helloWorldReference变量中的弱引用检索对象,因为它尚未被垃圾回收。由于已经存在对该对象的强引用,因此该对象永远不会被垃圾收集。
答案 1 :(得分:1)
WeakReference
和SoftReference
s不“协助”垃圾收集器,但它们提供了关于是否应该尽可能保留引用的提示。如果对象的唯一引用是弱或软,则GC可以收集对象。但是,除非JVM需要内存,否则具有SoftReference
的对象通常不会被垃圾回收。它们适用于缓存之类的东西。