是什么破坏了java中的局部变量?

时间:2014-12-21 06:25:47

标签: java garbage-collection

我怀疑方法局部变量仅在方法执行时才存在。此外,当EdenLong-generation块溢出(次要/主要GC)等时触发GC ...所以,如果方法体Eden的末尾没有溢出,所以不需要触发GC。尽管没有触发主要/次要GC,我们将销毁所有局部变量。怎么做?

3 个答案:

答案 0 :(得分:6)

垃圾收集器 - 收割机,有时也知道 - 按照自己的计划运行,并收集不参考的对象。 当然,在方法退出后无法引用局部变量,因为它们超出了范围,因此对于程序来说它们已经死了*,但它们仍然存在于堆上,直到GC运行。

在正常情况下(以及大多数异常情况),您无需告诉收割者什么时候开始工作。它会在需要时静静地来,带走那些不再需要的东西。这是使用高级语言工作的主要优点之一:可以安全地假设您永远不需要考虑管理死对象的释放等问题。你可以把它们扔到肩膀上,并且知道它们永远不会打扰你。我想有一些高性能,高需求的应用程序需要摆弄GC,但这是一个优化,除非你有相反的确实好的证据,否则应该总是假定为时过早。

*当然,除了返回到调用函数的局部变量,它可能成为该范围内的局部变量并获得更多的生命租约。一般来说,规则是:如果你的代码的某些部分仍然关心变量,它将不会被垃圾收集,如果程序的任何部分都不关心它,那么你不需要考虑它。

答案 1 :(得分:5)

方法局部变量(或只是"局部变量"因为它们通常被称为)被分配在每个线程的堆栈上。变量本身不受垃圾回收的影响。当方法调用终止(正常或异常)时,它们会自动回收。

物体是另一回事。对象(包括数组)通常在堆上分配 1 ,并且它们受垃圾回收的影响。


那么由方法分配并分配给局部变量的对象(或数组)呢?

首先,局部变量保存对象的引用。该对象存储在堆中(见上文)。

当垃圾收集器运行时(你通常不知道什么时候会这样!)它将检查任何现有的局部变量以查找仍在进行中的方法调用。变量包含对象的引用,这些对象被添加到要保留的对象列表中......并检查它们对其他对象的引用,等等。


因此,总之,当方法调用结束时,局部变量会自动销毁,但这些变量引用的对象将继续存在,直到GC(最终)发现它们无法访问为止。


1 - 最近的Hotspot JIT编译器有一个可选的优化,称为"转义分析"用于查找由方法调用创建的对象可以在线程堆栈上分配的情况。默认情况下不启用此功能。如果在堆栈上分配了一个对象,那么当方法调用结束时它将被回收。 GC没有参与。

2 - 您说:"当Eden或长代数据块溢出(次要/主要GC)等时触发GC ......" 。这不一定是这样。在各个空格填满之前,会触发一些低暂停收集器。但是,这并没有改变上述任何一个。

答案 2 :(得分:1)

Java虚拟机使用线性堆栈来管理(存储/访问)局部变量和方法参数,因此它只是将堆栈指针设置为没有声明本地和参数并继续运行的点。它不需要使用GC