当前位置: 首页 > 知识库问答 >
问题:

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

吴丁雷
2023-03-14

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

共有3个答案

白嘉志
2023-03-14

你无法控制这种行为。

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

一个字段只被访问一次或多次并不重要;它仍然会在L1d中结束。除非你有一个非临时的加载/存储;但是这个行为不能从Java访问。

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

有关更多信息,请参阅:https://shipilev.net/blog/2014/on-the-fence-with-dependencies/

毛镜
2023-03-14

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

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

但正如所说:作为开发者,你对此“没有发言权”。

容鸿畴
2023-03-14

不,Java语法不允许直接访问硬件。Java语言和虚拟机规范是管理如何解释Java代码的契约,它明确地以虚拟机而不是实际的虚拟机为目标。

从第1.2节:

Java虚拟机是Java平台的基石。它是该技术的一个组成部分,负责其硬件和操作系统的独立性、编译代码的小尺寸,以及保护用户免受恶意程序攻击的能力。

Java虚拟机是一种抽象的计算机器。像真正的计算机器一样,它有指令集,在运行时操作各种内存区域。使用虚拟机实现编程语言是相当常见的;最著名的虚拟机可能是UCSD帕斯卡的P-Code机器。

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

 类似资料:
  • 但它不起作用。我正在寻找适当的maven依赖。或者我应该从git签出它并部署在我们内部的ArtiFactory中?

  • 大家好,我有一个关于Java继承的具体问题。以下是我的代码 现在我的问题是,运行这个程序时,幕后到底发生了什么。 什么会遗传? 内存位置在哪里? 为什么第一个syso给4,第二个给5?(这一点我能在一定程度上理解,但澄清上述两个将有助于更清楚地理解它) 请引导

  • 我正在使用vue.js和vuex开发一个应用程序,它使用JWT令牌对JSON API服务器进行身份验证。所以我想知道存放JWT代币的最佳做法是什么? 如果我将其存储在vuex商店中,则页面刷新后它会丢失,因此用户需要再次登录,这不是很方便。 如果我将其存储在浏览器的本地存储中,它会在下次登录之前被弃用,然后假设身份验证令牌的组件会混淆。我不知道如何处理这个问题。 感谢你对此的暗示。

  • 问题内容: 我编写了一个简单的测试应用程序,以将某些内容记录到日志文件中。我正在使用 linux mint ,在应用程序执行后,我尝试使用以下命令查看日志: 但是文件消息既不经过测试也不存在。在下面可以找到我的代码。也许我做错了什么,文件没有存储在那儿,或者我需要启用Linux Mint中的登录功能。 问题答案: 在我的Ubuntu机器上,我可以在看到输出。 在RHEL / CentOS计算机上,

  • 对于我的一些模块,Intellij的想法不是导入依赖项和插件。只导入活循环。 当我在命令行编译时,POM是有效的。我已经删除了模块并重新导入它们。我删除了他们的项目,并重新导入它。 所以我想知道Intellij在模块上的想法信息被删除后是否有一些秘密缓存。

  • 我知道每个操作系统都有一个特定的目录,程序可以在其中存储数据。例如,在macOS中有一个名为 /Applications.的目录 我在哪里可以在Windows、Linux和macOS上存储来自java程序(多用户)的程序数据?有ystem.property?