Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java内存模型与局部变量_Java_Java Memory Model - Fatal编程技术网

Java内存模型与局部变量

Java内存模型与局部变量,java,java-memory-model,Java,Java Memory Model,这个问题与java内存模型有关 我有一个java方法: public class DataUtil{ public void process(){ int c=0; c=c+1; System.out.println(c); } } 在“System.out.println(c)”行中,println方法在哪里获取c变量的值并将其打印到屏幕上? CPU缓存或RAMJava内存模型并不规范这一点-它关注多线程程序的行为。 局部变量在堆栈上分配。函数的参数(如pr

这个问题与java内存模型有关

我有一个java方法:

public class DataUtil{
  public void process(){
    int c=0;
    c=c+1;

    System.out.println(c);
  }
}
在“System.out.println(c)”行中,println方法在哪里获取c变量的值并将其打印到屏幕上?
CPU缓存或RAM

Java内存模型并不规范这一点-它关注多线程程序的行为。

局部变量在堆栈上分配。函数的参数(如
println
)也通过堆栈传递-它们在调用之前被推到堆栈顶部(根据调用约定)。这是字节码中发生的事情,尽管JIT编译器或解释器也可能使用CPU寄存器,而不使用RAM中的堆栈。

Java内存模型没有规定这一点-它关注多线程程序的行为。

局部变量在堆栈上分配。函数的参数(如
println
)也通过堆栈传递-它们在调用之前被推到堆栈顶部(根据调用约定)。这是字节码中发生的事情,尽管JIT编译器或解释器也可能使用CPU寄存器,而不使用RAM中的堆栈。

要清楚,这个问题和答案只与具有一个线程的程序的行为有关。我下面说的许多事情可能不适用于多线程程序

println
方法在哪里获取
c
变量的值并在屏幕上打印?CPU高速缓存或RAM

Java内存模型(JLS 17.4)没有明确说明缓存和RAM。通常,它指定可见性行为,而不指定特定编译器实现该行为的方式。JMM规定,当线程写入变量并随后读取is时,存在“发生在”关系。before约束生成的代码以某种方式运行。然而,它并不要求采取任何特定的执行方法来实现这些限制

在您的示例中,JMM甚至没有对值是来自缓存还是来自RAM设置隐式约束。
c
变量只能由一个线程访问。(这是一个局部变量!)。因此编译器(理论上)可以在任何地方存储变量的值1。唯一的限制是在访问变量时使用最新的值。编译器只需要跟踪最新变量的保存位置

一般来说,JMM只对不同线程共享的变量和对象有一些有趣的说法


1-在寄存器中,在RAM中,在高速缓存中,在硬件堆栈上。。。如果你的硬件平台支持的话,即使是写在沙发背面的一张纸上


如果你在更广泛的意义上使用“记忆模型”,那么简单的答案是“我们不能说”

  • 在以主存和缓存的形式指定内存模型的语言(不是Java!)中,内存模型很可能不会约束此示例

  • 如果您不是在谈论任何特定的内存模型,而只是询问值是从缓存还是RAM中获取的,那么我们不能说。。。因为这是语言实现的一个实现细节。例如,JVM

我们可以高度肯定地说,实现将从本例中的某个地方获取并打印
c
的最新值

对于Java,JLS说它必须返回最新的值。(如果您想查看的话,可以在JLS 17.4中找到。)JLS将由Java实现决定如何做到这一点

可以安全地假设,任何JVM实现都会提出可靠的解决方案;i、 e.将使用变量的最新值。但是弄清楚细节将是一项艰巨的任务。。。而且(国际海事组织)不值得这样做。(驾驶汽车不需要了解沃尔沃264自动变速箱的内部结构。)



2-我们可以肯定,因为没有大量的单线程应用程序由于读取和写入变量的问题而无法工作的错误报告。此外,如果有任何疑问,可以检查JIT编译器源代码以了解它的功能,或者分析它生成的本机代码。

说得清楚,这个问题和答案只与具有一个线程的程序的行为有关。我下面说的许多事情可能不适用于多线程程序

println
方法在哪里获取
c
变量的值并在屏幕上打印?CPU高速缓存或RAM

Java内存模型(JLS 17.4)没有明确说明缓存和RAM。通常,它指定可见性行为,而不指定特定编译器实现该行为的方式。JMM规定,当线程写入变量并随后读取is时,存在“发生在”关系。before约束生成的代码以某种方式运行。然而,它并不要求采取任何特定的执行方法来实现这些限制

在您的示例中,JMM甚至没有对值是来自缓存还是来自RAM设置隐式约束。
c
变量只能由一个线程访问。(这是一个局部变量!)。因此编译器(理论上)可以在任何地方存储变量的值1。唯一的限制是在访问变量时使用最新的值。编译器只需要跟踪最新变量的保存位置

一般来说,JMM只对不同线程共享的变量和对象有一些有趣的说法


1-在寄存器中,在RAM中,在高速缓存中,在硬件堆栈上。。。甚至写在一张纸上也会推下