究竟什么是可用于垃圾收集的对象?

时间:2012-01-20 11:46:17

标签: java garbage-collection

我正在与我的应用程序争夺内存问题,并试图了解垃圾收集。如果我有以下代码:

public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   doAnotherThing();
   andEvenMoreThings();
}

所以我的问题是,在myObject之后,myObject.doSomething()是否可用于此对象的最后一次使用,或者someMethod()完成后,它将在范围之外?即垃圾收集是否足够聪明,虽然局部变量仍在范围内,但其余代码不会使用它?

6 个答案:

答案 0 :(得分:4)

“它来自范围”

public void someMethod() {
   MyObject myObject = new MyObject();
   myObject.doSomething();  //last use of myObject in this scope
   myObject = null; //Now available for gc
   doAnotherThing();
   andEvenMoreThings();
}

答案 1 :(得分:4)

你能做的最好的事情就是把你的代码放在一个有延迟的循环中并连接一个探查器。

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

如果你在Windows上并且设置了JAVA_HOME

  

%JAVA_HOME%/ bin / jvisualvm

这将启动一个分析器,您可以看到正在收集的对象和不收集的对象。在我看来,这是成为程序员的重要组成部分,以及查找内存泄漏的乐趣。

希望这有帮助

答案 2 :(得分:4)

在后面的java 6中,有escape analysis类型,JVM可以发现你的MyObject实例没有离开方法,因此它甚至可以完全放在堆栈上,你不需要任何GC就可以了。

答案 3 :(得分:3)

  

所以我的问题是,myObject.doSomething()是myObject.doSomething()的最后一次使用,还是在someMethod()完成后,myObject可用于垃圾收集?

前者。

  

即。垃圾收集是否足够聪明,虽然局部变量仍在范围内,但其余代码不会使用它?

GC看不到范围,它只看到寄存器,堆栈,全局变量以及从堆块到其他堆块的引用。因此范围无关紧要。

答案 4 :(得分:2)

本地范围外。对象可以重用,可以存在于本地范围内。即。它标记为gc。但实际上不是gc'ed。

答案 5 :(得分:2)

代码优化可能会注意到myObject的最后一个用法的位置,并使其可用于那里的垃圾收集,但从技术上讲,它将在变量不再引用它之前(通过被分配到别的东西)或超出范围。