java - final 成员变量有利于更好的 GC 吗?

标签 java optimization garbage-collection final

这个问题是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/

相关文章:

java - Hibernate 中的列名称

java - If 语句逻辑未按预期工作

php - 在 SQL 中查找并计算重复记录并按最大计数排序

c++ - 将 Sqrt(x) 计算为 x * InvSqrt(x) 在 Doom 3 BFG 代码中是否有意义?

mysql - 通过 OR 优化左连接?

java - 对象引用、线程和垃圾收集

php - 如果我有循环引用,我可以触发 PHP 垃圾收集自动发生吗?

java - 使用并发标记扫描 GC 收集器?

java - ArrayList 在 do..while 循环中未按预期工作

java - 在 ProcessBuilder 中执行 echo 命令