gpt4 book ai didi

java - JIT可以做这个字段访问优化吗?

转载 作者:搜寻专家 更新时间:2023-11-01 03:24:11 24 4
gpt4 key购买 nike

免责声明:请不要提供有关过早优化的建议。我只是好奇。

假设我想确保某个字段引用的某些对象可以尽快被垃圾回收。我正在使用像这样的自制单链表

class BigData {
byte[] someBigArray;
BigData next;
}

private BigData bigData;

然后像这样迭代

while (bigData != null) {
process(bigData);
bigData = bigData.next;
}

JIT可以自由改成如下吗?

BigData tmp = bigData;
while (tmp != null) {
process(tmp);
tmp = tmp.next;
}
bigData = null;

假设没有对任何 BigData 实例的其他引用。假设 process 是一个简单的可内联方法,不访问字段 bigData。这两个片段是等效的(假设中间没有抛出异常),唯一的区别是第二个片段将字段访问从循环移到了外部。

重复免责声明:请不要提供有关过早优化的建议。我只是好奇。


要回答评论“即使您‘想要’的更改是 JIT 所做的,为什么这会使 GC 更快/更早地收集它们?”:如果 JIT 进行更改,那么所有的大对象只能在循环之后收集。如果没有,则每次循环前进时都会有一个对象符合 GC 的条件。

附录:

实际上,只要 JIT 可以自由执行上述转换,它就可以改为执行以下操作:

BigData tmp = bigData;
bigData = null;
while (tmp != null) {
process(tmp);
tmp = tmp.next;
}

我看不出这里有任何缺点,它使所有对象在原始代码中都可以立即收集。

最佳答案

好吧,优化器可以优化

while (bigData != null) {
process(bigData);
bigData = bigData.next;
}

进入

BigData tmp = bigData;
while (tmp != null) {
process(tmp);
tmp = tmp.next;
}
bigData = null;

如果 bigData 字段不是volatile 并且 process 方法没有禁止此优化的副作用。

但在实践中,代码转换(如果有的话)看起来会完全不同。优化器通常会展开循环,创建执行一定次数迭代的代码块,并在向后跳转之前执行字段存储操作。所以有一些垃圾收集器可以跳入的“保存点”。但是如果 process 方法包含访问 bigData 字段或可能分配内存等的代码,则该字段存储将在每次调用之前执行。

关于java - JIT可以做这个字段访问优化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19547284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com