gpt4 book ai didi

java - 如果主引用指向null,则WeakReference或SoftReference有何不同?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:13 29 4
gpt4 key购买 nike

我正在阅读有关 WeakReference SoftReference 的信息。

发现以下内容:

弱参考:

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

对其内部工作方式感到困惑吗?之前我曾想过,它会克隆对象,然后弱引用它,但是从输出来看,它看起来并不像。

最佳答案

长话短说

没有一个对象有很强的引用,因此对象可以进行垃圾回收。但是不同的引用类型将确定垃圾收集器如何确定对象的垃圾收集的优先级。

根据不同的参数,在垃圾回收周期中发生的实际详细信息可能会有所不同。
其中一些参数如下:

  • JRE / VM版本
  • 选择的实际垃圾收集算法
  • 系统中的可用内存
  • 系统资源

  • 原则上,垃圾收集器会尝试快速有效,以免长期或短期内不影响性能,同时确保有足够的可用内存。

    因此,在垃圾回收期间,垃圾回收器将尝试通过垃圾回收某些对象来释放一些内存。
    垃圾收集器最终将确定它将释放多少内存以及要收集哪些对象以进行垃圾收集。垃圾收集器不一定每次运行时都会垃圾收集所有符合条件的对象。

    因此,可以说有资格进行垃圾回收的对象将是具有不同优先级的垃圾回收。因此,垃圾回收的优先级如下:
  • 未引用的对象具有被垃圾回收的最高优先级。
  • 弱引用的对象是接下来要进行垃圾收集的更多合格对象。
  • 软引用的对象是接下来要进行垃圾收集的更多合格对象。

  • 基于此优先级划分,较弱引用的对象比较软引用的对象更容易收集垃圾。但是,何时垃圾收集每个对象的决定和责任仅由垃圾收集器来决定。

    该定义是关于优先级(急切性)而不是精确的规则,因此可以期望观察到:
    从长远来看(如果在许多不同的JRE中以及在不同的情况下观察到),弱引用对象倾向于在软引用对象之前被垃圾回收。

    “软引用与弱引用完全一样,只是软引用不急于丢弃它所引用的对象。”在此引用此答案; Soft vs Weak reference
    Java还包括Phantom引用,这是一个相关概念。 Phantom References

    在问题更新后进行更新:

    在第一个示例中:
    null这是预期的,因为它是已显式设置为null的helloWorld变量中的强引用。
    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变量中的弱引用将检索对象,因为尚未对其进行垃圾回收。由于已经存在对对象的强引用,因此永远不会对对象进行垃圾回收。

    关于java - 如果主引用指向null,则WeakReference或SoftReference有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49450059/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com