在Java中,我可以决定字段存储在哪里:寄存器、缓存还是RAM?

在Java中,我可以决定字段存储在哪里:寄存器、缓存还是RAM?,java,Java,我知道这是自动完成的——访问数据的频率越高,存储的数据就越接近处理器。但是我能用Java语法影响它们的位置吗?按照我的理解,Volatile将数据放在3级缓存或RAM中,因为它对所有线程都是可见的,对吗?您无法控制这种行为 如果CPU读取一个对象的字段,该对象将被拉入L1d。这与字段是否易失性无关 一个字段只被访问一次或多次并不重要;它仍将在L1d中结束。除非您有非临时加载/存储;但这种行为无法从Java访问 Volatile可防止编译器和CPU/内存子系统级指令的重新排序。对于X86,由于X8

我知道这是自动完成的——访问数据的频率越高,存储的数据就越接近处理器。但是我能用Java语法影响它们的位置吗?按照我的理解,Volatile将数据放在3级缓存或RAM中,因为它对所有线程都是可见的,对吗?

您无法控制这种行为

如果CPU读取一个对象的字段,该对象将被拉入L1d。这与字段是否易失性无关

一个字段只被访问一次或多次并不重要;它仍将在L1d中结束。除非您有非临时加载/存储;但这种行为无法从Java访问

Volatile可防止编译器和CPU/内存子系统级指令的重新排序。对于X86,由于X86的TSO内存模型,您可以免费获得易失性读取(acquire semantics)。易失性写入是通过停止前端执行加载直到存储缓冲区耗尽来实现的。这可以防止将较旧的存储和较新的加载重新排序到不同的地址

有关更多信息,请参阅:
否,Java语法不允许直接访问硬件。这是一个控制Java代码如何解释的契约,它是显式地以虚拟机而不是实际的虚拟机为目标编写的

发件人:

Java虚拟机是Java平台的基石。信息技术 该技术的组件是否负责其硬件和软件 操作系统独立性,编译代码小, 以及保护用户免受恶意程序攻击的能力

Java虚拟机是一种抽象计算机器。像一个真正的 计算机,它有一个指令集和各种操作 运行时的内存区域。实施 使用虚拟机的编程语言;最著名的虚拟图书馆 机器可能是UCSD Pascal的P代码机器


Java虚拟机甚至不需要有可访问的寄存器或缓存。从规范的角度来看,图灵机可以很好地实现一致的Java虚拟机。

Java在很大程度上在优化方面的工作方式不同。您可以让开发人员说明在代码中要做什么。然后,在运行时,即时编译器查看正在发生的事情,然后(如果必要的话)将“缓慢”的java字节码转换为高度优化的机器码

换句话说:JIT决定哪些代码值得优化。这可能包括优化的“数据布局”


但正如所说:作为一名开发人员,您在这方面没有发言权。

这是否回答了您的问题?“但是我能用Java语法影响它们的位置吗?”-不,这不是你(作为程序员)的决定,特别是Java规范不知道这些概念。因此,某些编译器或运行时可能以一种方式运行,而另一些运行时可能以不同的方式运行。决定将变量放置在何处是JIT的工作,而不是开发人员的工作,因此您无法控制它。而且规范中从来没有说volatile变量放在l3缓存中,它只是为您提供了一些关于它们的读/写行为的保证。没有明确的语言支持或JVM规范并不等于不影响较低级别上发生的事情。@pveentjer-您可以合理地猜测JVM实现会做什么,甚至在其源代码中查找特定版本;但总的约定是,JVM实现可以选择做任何事情,只要它们遵守规范。这种行为你不能在“源代码”中查找。您需要了解硬件实际上是如何工作的。@pveentjer针对每个受支持的体系结构,并准确描述什么将在何时何地运行。当然,编写它的人对硬件有着深刻的理解。我并不是说代码很简单,但只要有足够的时间,您就可以通过查看代码来了解如何为特定的JVM和体系结构分配寄存器。“寄存器”并不那么重要,因为它们是体系结构寄存器,而不是CPU内部实际发生的事情(架构寄存器由处理器(ROB)重命名并分配给物理寄存器)。有关通过确保缓存线处于适当状态将对象加载到L1D的所有内容都不是ISA的一部分;而是微体系结构的一部分。而这正是OP所要求的。因此,仅仅盯着生成的程序集不足以理解实际发生的情况。一旦实时优化器运行如果它检测到代码没有任何影响,那么它很可能会完全删除代码——因此,在消除死代码之后,没有L1d或任何其他分配。