局部变量上的垃圾收集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了局部变量上的垃圾收集相关的知识,希望对你有一定的参考价值。
我是一名进入Java世界的C ++程序员。我无法摆脱不得不让Java垃圾收集器进行清理的坏感觉。
例如,这段代码将如何在Java中运行?
public void myFunction() {
myObject object = new myObject();
object.doSomething();
}
当myFunction()退出时,是否会删除局部变量对象?
在退出之前是否必须将对象设置为null,或者它是否超出范围并被GC删除?或者,在最坏的情况下,它会像在C ++中那样泄漏吗?
它将在不再使用后的某个时刻被垃圾收集。我相信Java的当前实现它实际上会持续到方法结束,而.NET中的垃圾收集器更具侵略性。 (我不知道即使在Java中是否有任何保证。通常,您只希望本地变量在调试时保持超出其最后可能的读数。)
但不,您不需要将变量设置为null,这样做会损害可读性。
方法退出后,对象不太可能立即收集垃圾;这取决于GC运行的时间......当然,如果其他任何东西保留在对象的引用上,它可能无法进行垃圾收集。不要忘记变量的值只是一个引用,而不是对象本身。 (这可能需要一段时间才能习惯来自C ++。)
GC至少在内存限制接近时完成工作,因为超出范围的变量引用的任何对象都可以被垃圾收集,但是最后一个退出块的超出范围的局部变量存在意外行为。
要深入了解,让我们进行比较:
{
final List myTooBigList = new ArrayList();
... overfill the list
}
somethingRunOutOfMemory();
somethingRunOutOfMemory()
,因为myTooBigList
不是GCable,尽管不再有范围,并且声称更多的内存,不像以下:
{
final List myTooBigList = new ArrayList();
... overfill the list
}
Object fake = null;
somethingDoesNotRunOutOfMemory();
fake
的影响将堆栈指针移回并让myTooBigList
GCable,然后GC在内存限制接近时立即执行其工作。令人惊讶的是(至少在我正在测试的jvm中)我们必须明确地在同一级别重用堆栈。一旦块退出,可以预期局部变量是GCable,但我想这是对性能的妥协。它会使字节码复杂化。
与C类似,局部变量位于帧旁边的堆栈中。堆栈指针保留了范围内局部变量所需的空间。当重用堆栈时,{exited block}的局部变量变为GCable,即:在同一堆栈级别,函数返回后或退出评估(catch,循环条件)之后声明局部变量之后。
他们是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
{ } declare=value : after any declaration+affectation that reuses stack
它们之后才是GCable:
try { } : after nothing caught
for { } : after exit by break
while { } : after exit by break
do { }
if { }
{ }
注意:对于实验室,运行GC然后将WeakReference(my variable)
与null
进行比较。
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中,当没有人再指向一个对象时,它将被垃圾收集,或者至少它可用于垃圾收集。这里不需要将其设置为null。如果您的对象将存在于App中,则有时需要将对象引用设置为null,但是它所持有的引用需要进行垃圾回收。在这种情况下,您选择发布参考。
以上是关于局部变量上的垃圾收集的主要内容,如果未能解决你的问题,请参考以下文章