Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最终字段如何不泄漏内存?_Java_Memory Leaks_Garbage Collection_Final - Fatal编程技术网

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

Java 最终字段如何不泄漏内存?,java,memory-leaks,garbage-collection,final,Java,Memory Leaks,Garbage Collection,Final,毫无疑问,多年来我一直在使用final关键字来表示在实例/类的生命周期内不应更改的字段。我突然想到了这一点 举个例子: public class TestFinalGC{ private TestFinalGC(){} private final Object obj = new Object(); public static void main(String []args){ TestFinalGC instance = new TestFin

毫无疑问,多年来我一直在使用
final
关键字来表示在实例/类的生命周期内不应更改的字段。我突然想到了这一点

举个例子:

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.
     }
}
obj
成员如何在此处不泄漏?
final
字段是否会自动weakreference,这样,如果对父项的强引用为null,它们就有资格进行垃圾收集

更新:

所以我的这个问题是建立在“可达性”和强/弱引用密切相关的前提下的。这让我相信嵌套引用应该总是“强可及”。因此,我在所有对象中都会将嵌套对象引用设为空,但从我收到的所有注释来看,显然不应该这样

那么,关于“可访问性”,如果父引用不再可访问,那么仅仅是嵌套对象引用不再被视为“可访问”吗


这个问题的前提可能是不正确的,但这里仍然有有趣的信息需要整合。

正如Makoto所建议的,就GC而言,变量声明中的
final
没有什么特别之处。在您的示例代码中

private final Object obj = new Object();
将与垃圾收集同时进行

private Object obj = new Object();
这两个都是强引用,但都是无效的,并与其父类TestFinalGC实例一起被垃圾收集。这是因为当实例是GC'd时,引用字段也被销毁,引用不再存在。因此,obj的参考计数减少1

然而,你应该写一些类似的东西吗

Object x = myTestFinalGC.obj; // only works if your obj is not private, of course
然后该对象将不会被垃圾收集,因为它仍然有一个引用在周围徘徊(假设这一特定代码行位于另一个类实例中,当myTestFinalGC被垃圾收集时,该类实例仍然处于活动状态)


tl;dr:当内存分配的硬引用计数降至零时(当然,收集器会运行),内存分配将被垃圾收集.
final
不会改变这一事实。

可能重复“否”,但答案仍然有效。
final
没有任何特殊之处使其不符合垃圾收集的条件。@rpg711只有在排除可访问性的情况下。当final字段本身不再可访问时,它才符合GC的条件。此时,它引用的所有内容都变得不可访问且可能符合条件(例如,除非通过另一个引用可以访问)。当清除
Root->instance
时,包含最终字段的实例将不再可访问,因此,如果没有其他引用,最终字段引用的任何内容也将不再可访问。不可访问与弱引用不同。您可以将对象视为村庄,将引用视为单向引用从一个村庄到另一个村庄的道路。如果您只能使用a村的道路前往B村,并且如果再也没有通往a村的道路(即a村无法到达),那么当然B村也不再是可访问的。GC将因此收集A和B。当硬引用计数降至零时,内存分配将被垃圾收集:不,那是不正确的。可访问性是重要的,而不是引用计数。否则,GC将永远不会收集具有循环引用的对象的图形。我尝试简单地解释这个概念。OP在理解GC的条件方面似乎有问题。所以我不想让事情变得更复杂。谢谢你指出这一点。@velis我不会说问题,更重要的是,这个问题所基于的前提很可能是不正确的。我还想指出,我并不完全是l追求简单。有一段时间,我还认为不可访问的对象符合GC的条件,嵌套对象在其父对象不再可访问时也不可访问。但我深入研究了这意味着什么,对这些东西如何工作的更深入解释实际上对我很有启发。@velis well,int事实上,这对我来说也是相当荒谬的,因为如果这种行为真的存在的话,我所从事的几乎所有项目都会有大量的内存泄漏。但是,我链接到的关于可访问性的oracle文档进一步让我困惑,并使我开始怀疑“显而易见”的问题真相。我明白了。我必须承认,我从来没有深入研究过GC,以至于能够进一步解释它。我发现JB Nizet、kjkrum和aquaraga后来的评论非常翔实和完整。我甚至不确定thare是一个更深层次的解释。GC是一个简单的概念,否则实施起来成本太高。