Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.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_Garbage Collection - Fatal编程技术网

Java 对象在哪一点上可用于垃圾收集?

Java 对象在哪一点上可用于垃圾收集?,java,garbage-collection,Java,Garbage Collection,我正在与我的应用程序的内存不足问题作斗争,并且正在设法解决垃圾收集的问题。如果我有以下代码: public void someMethod() { MyObject myObject = new MyObject(); myObject.doSomething(); //last use of myObject in this scope doAnotherThing(); andEvenMoreThings(); } 所以我的问题是,myObject在myObjec

我正在与我的应用程序的内存不足问题作斗争,并且正在设法解决垃圾收集的问题。如果我有以下代码:

public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   doAnotherThing();
   andEvenMoreThings();
}
所以我的问题是,
myObject
myObject.doSomething()
这是该对象的最后一次使用之后,还是在
someMethod()
完成之后,它超出范围后,是否可以进行垃圾收集?也就是说,垃圾收集是否足够聪明,可以看到尽管局部变量仍在作用域中,但代码的其余部分不会使用它?

“在它超出作用域的地方”


在局部作用域结束后。as对象可以重用,并且可以存在于本地范围内。它被标记为gc。但实际上不是gc'ed。

代码优化可能会注意到myObject的最后一次使用位置,并使其可用于垃圾收集,无论从技术上讲,直到变量不再引用它为止(通过分配给其他对象)或者超出范围。

您可以做的最好的事情是将代码延迟地放入循环中,并将探查器连接到它

如果您使用的是更高版本的Java,那么JVisualVm是标准的

如果您在windows上,并且拥有JAVA_HOME set

%JAVA_HOME%/bin/jvisualvm

这将启动一个探查器,您可以看到正在收集的对象和未收集的对象。在我看来,这是作为一名程序员必不可少的一部分,发现内存泄漏也是一件很有趣的事情


希望这对以后的java 6有所帮助,JVM可以发现您的MyObject实例没有离开该方法,所以它甚至可以将它完全放在堆栈上,您根本不需要任何GC

所以我的问题是,myObject是否可以在myObject.doSomething()之后(这是该对象的最后一次使用)进行垃圾收集,或者在someMethod()完成之后(它超出范围)进行垃圾收集

前者

也就是说,垃圾收集是否足够聪明,可以看到尽管局部变量仍在作用域中,但代码的其余部分不会使用它


作用域对GC不可见,GC只看到寄存器、堆栈、全局变量和从堆块到其他堆块的引用。所以作用域是不相关的。

它将发生在第4行,因为您显式地取消了对myObject=null的引用//现在可以在问题中使用gc,但它将在大括号后结束,因为没有解引用。您不需要为myObject指定null。在someMethod()的执行结束时,myObject将被标记为gc。当然,这只是为了突出显示方法内部的合格案例。eligble案例很少使用,除非您碰巧知道引用指向大型数据结构,并且在一段时间内不会超出范围。然后显式设置为null是很有用的。我认为您在错误的上下文中使用了“取消引用”。仅仅因为垃圾收集器看到它没有被使用,它不会选择立即释放它-您不应该编写依赖于不可预测事件行为的代码;)如果您有内存问题,则可能是错误地保留了对某些内容的引用:(嗯,谢谢伊莎,我想你是对的。我会更新这个问题的标题。谢谢迪恩乌姆伯恩,我确实理解。我只是想了解更多关于垃圾收集的工作方式和时间。我认为JLS实际上不允许这样做,或者至少hotspot不允许这样做。NET确实允许我们必须这样做避免在我们想要的时间之前收集具有副作用的对象(如计时器)。至少在Java中,我从来没有偶然提到过会让我感到惊讶的东西。有趣的是,代码优化是指JVM执行、GC执行还是代码编译?
public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   myObject = null; //Now available for gc
   doAnotherThing();
   andEvenMoreThings();
}