在Java中将final用于变量会改善垃圾回收吗?

今天,我和我的同事们讨论了如何final在Java中使用关键字来改善垃圾回收。

例如,如果您编写如下方法:

public Double doCalc(final Double value)

{

final Double maxWeight = 1000.0;

final Double totalWeight = maxWeight * value;

return totalWeight;

}

final在方法退出后,在方法中声明变量将有助于垃圾回收从方法中未使用的变量中清除内存。

这是真的?

回答:

这是一个稍有不同的示例,其中包含最终引用类型字段而不是最终值类型局部变量:

public class MyClass {

public final MyOtherObject obj;

}

每次创建MyClass实例时,都将创建对MyOtherObject实例的传出引用,GC必须遵循该链接来查找活动对象。

JVM使用标记扫描GC算法,该算法必须检查GC“根”位置中的所有实时裁判(如当前调用堆栈中的所有对象)。每个活动对象都被“标记为”活动,活动对象所引用的任何对象也都被标记为活动。

标记阶段完成后,GC会扫描堆,释放所有未标记对象的内存(并压缩剩余活动对象的内存)。

同样,重要的是要认识到Java堆内存被划分为“年轻”和“旧”。所有对象最初都是在年轻一代(有时称为“苗圃”)中分配的。由于大多数对象都是短命的,因此GC在从年轻一代释放最新垃圾方面更加积极。如果某个对象在年轻一代的收集周期中幸存下来,则将其移入旧一代(有时称为“终身一代”),该对象的处理频率较低。

因此,我想说的是:“不,’最终’修饰符无法帮助GC减少工作量”。

我认为,在Java中优化您的内存管理的最佳策略是尽快消除虚假引用。您可以通过在使用完对象后立即为对象引用分配“ null”来做到这一点。

或者更好的是,最小化每个声明范围的大小。例如,如果您在1000行方法的开头声明了一个对象,并且该对象在该方法作用域关闭之前(最后一个大括号)一直保持活动状态,则该对象可能会存活更长的时间必要。

如果您使用小的方法,只有十几行代码,则在该方法中声明的对象将更快地超出范围,并且GC将能够在效率更高的范围内完成大部分工作年轻一代。除非绝对必要,否则您不希望将对象移入较早的一代。

以上是 在Java中将final用于变量会改善垃圾回收吗? 的全部内容, 来源链接: utcz.com/qa/433078.html

回到顶部