垃圾收集本地variables

我是一个进入Java世界的C ++程序员。 而且我不能摆脱让Java垃圾收集器清理我的不好的感觉。

例如,这个代码如何在Java中运行?

public void myFunction() { myObject object = new myObject(); object.doSomething(); } 

当myFunction()退出时,局部variables对象会被删除吗?

在退出之前是否必须将对象设置为null,还是会超出范围并被GC删除? 或者,最坏的情况下,它会像C ++一样泄漏吗?

在不再使用之后的某个时刻 ,它将被垃圾收集。 我相信在Java的当前实现中,它实际上会一直持续到方法结束,而.NET中的垃圾收集器更具侵略性。 (即使在Java中我也不知道是否有任何保证,通常情况下,只要本地variables在debugging时保持超出最后可能的读取范围。

但是,不,你不需要将variables设置为null,这样做会损害可读性。

方法退出后,对象不可能立即收集垃圾; 这取决于GC运行的时间……当然,如果还有其他任何东西持有对该对象的引用,则无论如何都可能不符合垃圾回收的条件。 不要忘记,variables的值只是一个引用,而不是对象本身。 (这可能需要一段时间才能习惯来自C ++)。

我遇到这样的代码:

 { final List myTooBigList = new ArrayList(); ... overfill the list } somethingRunOutOfMemory(); 

somethingRunOutOfMemory(),因为myTooBigList不是GCable,尽pipe不在范围内。

像在C中一样,局部variables位于框架旁边的堆栈中。 堆栈指针保留了作用域中局部variables所需的空间。 当堆栈被重用时,块的局部variables变成GCable。 当超出范围时,指针立即被新的局部variables移回。

他们是GCable之后:

 try { } catch : after exit by catch because catch reuses stack for { } : after exit loop condition because evaluation reuses stack while { }: after exit loop condition because evaluation reuses stack { } followed by any local declaration that reuses stack 

他们不是GCable之后:

 try { } finally try { } catch : after nothing caught for { } : after break while { } : after break do { } while : after loop condition if { } { } not followed by a local declaration 

如果我想要一个本地的GCable我写:

 { final List myTooBigList = new ArrayList(); ... overfill the list } Object fake = null; somethingDoesntRunOutOfMemory(); 

假的影响移动堆栈指针,并使myTooBigList GCable。 令人惊讶的是(至less在我正在testing的jvm中),我们必须明确地重用堆栈。 一旦块被退出,预计局部variables会变得更加可预测,但是我想这是一个与性能的妥协。 这会使字节码复杂化。

注:要testing一个variables是否为GCable,我运行GC然后比较WeakReference(我的variables)为空。

 final WeakReference gctest; { final List myTooBigList = new ArrayList(); gctest = new WeakReference(myTooBigList); ... overfill the list } Object fake = null; System.gc(); assert gctest.get() == null; 

它会超出范围。 在Java中,当没有人指向一个对象时,它将被垃圾收集,或者至less可以用于垃圾收集。 不需要在这里设置为null。 如果你的对象在你的应用程序中生存,有时需要设置一个对象引用为空,但是它所持有的引用需要被垃圾收集。 在这种情况下,您正在select发布参考。