问题描述
我试图更好地了解JIT编译器在可变变量值缓存方面如何为java工作.考虑一下此问题中给出的示例: with while循环和线程的无限循环问题:
I'm trying to better understand how does the JIT compiler work for java in respect to volatile variable value caching.Consider the example presented in this question:Infinite loop problem with while loop and threading:
boolean loaded = false; // not volatile!!!
private boolean loadAsset() {
new Thread(new Runnable() {
@Override
public void run() {
// Do something
loaded = true;
}
}).start();
while (!loaded) {
System.out.println("Not Loaded");
}
System.out.println("Loaded");
return false;
}
由于未将变量 loaded 声明为volatile,因此允许将JIT编译器缓存"在注册表中.据说这在理论上可能会导致无限循环,因为执行循环的线程可能在某个时间点看不到该变量是从另一个线程更新的.
Since the variable loaded is not declared volatile, the JIT compiler is allowed to "cache" the variable in the registry. It is said that this could in theory result in an infinite loop because the thread that executes the loop might not see that the variable was updated from another thread at some point of time.
但是允许" 到底是什么意思?变量是否有可能有时被缓存,这意味着如果我在同一JVM中运行同一段代码(不关闭JVM)一百万次,则JIT编译器可能会在某个时候决定缓存变量并产生无限循环?还是JIT编译器是一致的,这意味着它将决定是否缓存该变量,并且该决定将在JVM的整个生命周期中对这段代码的所有百万次执行表示反对?
But what exactly does "allowed" to cache mean? Is it possible for the variable to get cached sometimes, meaning that if I run this same piece of code in the same JVM (without shutting the JVM down) a million times, the JIT compiler might at some point decide to cache the variable and produce an infinite loop? Or is the JIT compiler consistent, meaning that it will either decide to cache the variable or not and that decision would stand off for all million executions of this piece of code through out the life cycle of the JVM?
推荐答案
此处的缓存发生在硬件级别,在该级别,CPU可能会决定从其缓存中读取变量的值,从而丢弃其他线程在其自己的缓存中写入的内容.
Caching here happens on the hardware level where the CPU might decide to read the value of the variable from its cache discarding what other threads have written on their own caches.
但是JIT
可能会优化循环并将其变成无限循环,因为没有在循环内部设置布尔标志,这与从缓存中读取陈旧值没有必要.
The JIT
however, might optimise the loop and turn it into and infinite loop because the boolean flag is not set inside the loop, which is not necessary the same as reading a stale value from the cache.
"允许缓存"在这里可能解释为,JIT不必在读取变量时发出fence instruction
.
"Allowed to cache" here might be interpreted as, the JIT is not obliged to issue a fence instruction
upon reading the variable.
这篇关于Java JIT编译器优化-在可变变量值缓存方面JIT是否一致?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!