简体   繁体   English

最终字段如何不泄漏内存?

[英]How do final fields NOT leak memory?

I have been, without a question, using the final keyword for years to denote fields that should not change for the lifetime of an instance/class. 毫无疑问,我多年来一直使用final关键字来表示在实例/类的生命周期内不应更改的字段。 Suddenly this occured to me... 突然这发生在我身上...

So given this example: 因此,给出此示例:

public class TestFinalGC{

    private TestFinalGC(){}

    private final Object obj = new Object();

     public static void main(String []args){
         TestFinalGC instance = new TestFinalGC();
         // instance Ref -> actual instance ->? obj ref-> actual obj
         System.out.println(instance.obj);
         instance = null;
         //say GC makes sweep here... what happens?
         //lets assume theres more code, obj would obviously be eligible for GC on app exit.
     }
}

How does the obj member NOT leak here? obj成员如何在这里不泄漏? Are final fields automatically WeakReferences such that if the strong references to parent(s) are nulled, they are eligible for garbage collection? final字段是否自动产生WeakReferences,从而如果对父级的强引用为空,则它们有资格进行垃圾回收?

The JLS does not seem to note anything special about final JLS似乎没有注意到关于final的任何特别之处

Update: 更新:

So this question of mine was founded on the premise that "reachability" and strong/weak references are closely related. 因此,我的这个问题是建立在“可达性”和强弱引用紧密相关的前提下的。 There is this confusing oracle doc on reachability that leads me to believe that nested references should always be "strongly reachable". 关于可访问性 ,这是一个令人困惑的oracle文档 ,使我相信嵌套引用应该始终是“强烈可访问”的。 Hence, I do null my nested object references in all my objects, but it appears that this obviously should not be the case from all of the comments I am receiving. 因此,我确实在所有对象中都没有嵌套对象引用,但是从我收到的所有注释看来,显然不是这种情况。

So regarding "reachability", then, is it simply just that nested object references are no longer considered "reachable" if parent references are no longer reachable? 那么,关于“可到达性”,如果父引用不再可访问,嵌套对象引用就不再被视为“可访问”了吗?

It could be is true that the premise of this problem is incorrect, but there is still intriguing information to consolidate here. 这个问题的前提可能是不正确的,但是这里仍然有有趣的信息需要合并。

As Makoto suggested, there is simply nothing special about final in variable declarations as far as GC is concerned. 正如Makoto所建议的那样,就GC而言,变量声明中的final根本没有什么特别的。 In your example code 在您的示例代码中

private final Object obj = new Object();

will be garbage collected at the same time as 将在与

private Object obj = new Object();

Both are strong references, but are invalidated and garbage collected together with their parent class TestFinalGC instance. 两者都是强引用,但都无效且与它们的父类TestFinalGC实例一起被垃圾回收。 That is because when the instance is GC'd, the reference fields are destroyed as well and the references do not exist any more. 这是因为当实例经过GC处理后,引用字段也会被破坏,并且引用不再存在。 obj's reference count thus decreases by one. obj的引用计数因此减少一。

However, should you write something like 但是,你应该写类似

Object x = myTestFinalGC.obj; // only works if your obj is not private, of course

Then the object will not be garbage collected because it will still have one reference lingering around (assuming this particular line of code is in another class instance that remains alive when myTestFinalGC is garbage collected. 然后,该对象将不会被垃圾回收,因为它仍然会有一个引用徘徊(假设这段特定的代码行在另一个类实例中,当myTestFinalGC被垃圾回收时,该类实例仍处于活动状态。

tl;dr: memory allocations are garbage collected when their hard reference count drops to zero (and the collector runs, of course). tl; dr:内存分配在其硬引用计数降至零(当然,并且收集器运行)时被垃圾回收。 final doesn't change this fact. final不会改变这一事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 最终和内存泄漏 - final and memory leak 恒定的静态字段会导致Web应用程序中的内存泄漏吗? - Do constant static fields cause memory leak in an web application? 不要将Android上下文类放在静态字段中; 这是内存泄漏 - Do not place Android context classes in static fields; this is a memory leak Java内存模型中的final字段 - final Fields In The Java Memory Model 如何检查内存泄漏? - How to check memory leak? “警告:不要将 Android 上下文类放在静态字段中; 这是内存泄漏(也会破坏 Instant Run)” - “Warning: Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)” 不要将 Android 上下文类放在静态字段中。 这是内存泄漏。 为什么? - Do not place Android context classes in static fields. this is a memory leak. why? “请勿将Android上下文类放在静态字段中; 这是内存泄漏”-静态视图的Lint警告 - “Do not place Android context classes in static fields; this is a memory leak” - Lint Warning for static View 警告 - 内存泄漏 - 静态字段中的上下文类 - Warning - Memory Leak - Context classes in static fields 如何诊断由Java程序引起的C内存泄漏? - How do you diagnose a leak in C memory caused by a Java program?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM