这个问题是continuation of this one但要求更具体的场景。
假设我们有以下类:
public class Person {
private Foot left, right;
public Person(Foot left, Foot right) {
this.left = left;
this.right = right;
}
}
我想知道如果我们把下面的类变成下面这样,是否可以从 GC 的角度对其进行优化:
public class Person {
private final Foot left, right;
public Person(Foot left, Foot right) {
this.left = left;
this.right = right;
}
}
如果我正在看这个类,我可以立即知道左右变量永远不能提前设置为 null。这意味着 GC 唯一需要为此类收集左右对象(并减少对它的引用)的时间是对父 Person 类的引用达到零时。这也应该意味着它可能能够在收集左脚和右脚对象的同时收集人;也导致更少的运行和加速。
因此,在这个例子中,将私有(private)成员变量标记为 final 是否意味着代码会导致垃圾收集中的轻微加速(或者它可能用作加速点)?
最佳答案
分配给字段不会触发任何垃圾收集器工作或引用计数调整,因为 Java GC 不使用引用计数 (*)。所以答案是将字段声明为 final
对垃圾收集器性能没有影响。 (收集器的跟踪阶段必须检查字段是否为 final
。
可以想象,将一个字段声明为final
可以帮助JIT 编译器的数据流分析和内存获取的优化。但是,将其用作将字段更改为 final
的理由并不是一个好主意。如果您打算这样做,请出于正确性原因(即在并发上下文中使构造安全)或出于风格原因(即使代码更易于理解和维护)。
(* 没有主流 Java 实现依赖引用计数来实现内存管理。理论上可能有人可能实现使用引用计数的 JVM,但传统观点认为引用计数效率极低...更不用说并发性、收集周期等方面的问题了。)
关于java - final 成员变量有利于更好的 GC 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6260039/