堆分配是否总是意味着立即访问 RAM?

如何解决堆分配是否总是意味着立即访问 RAM?

假设 Java JIT 编译代码,例如构建链表, new Link(及其构造函数)是否可以在根本不访问 RAM 的情况下返回?换句话说,VM 是否可以至少在理论上只在处理器缓存中进行分配,而在刷新时才进行实际的内存分配(例如,一次性分配整个列表或一个列表段)?

除了它本身很有趣之外,当我考虑在与新对象创建配对时使用 volatile 关键字的实际相对损失时,出现了这一点。假设一个可变列表定义如下:

class Link<E> {
    final E elem;
    Link<E> next = null
    Link(E e,Link<E> tail) {
        elem = e;
        next = tail;
    }

    public void append(E e) {
        next = new Link(e,null);
    }
}

可以在字段 volatile 中添加 next 关键字影响对 append 重复调用的性能(可能不久之后取消引用整个集合,释放内存用于垃圾收集),限制JVM 能够以一种重要的方式(至少在理论上)对代码进行优化?

解决方法

向字段添加 volatile 关键字是否会影响重复调用 append 的性能(可能不久之后会取消对整个集合的引用,释放内存以进行垃圾收集),从而限制了 JVM 能够对代码进行的优化重要的方式(至少在理论上)?

答案当然是肯定的。 JVM 是一个抽象的概念。关于某些 Java 代码性能的概括性陈述仅属于以下几类:

  • Java 内存模型保证这可以正常工作(但这总是关于某些东西是否有问题(有时以现有 VM 无法重现的方式存在问题,但仍然存在问题,因为某些未来版本可能会破坏您的代码)这会是你的错))——不过,这与性能特征无关。

  • 声明如下:对于所有主要平台和所有主要 VM 版本,在其当前版本中,此代码将执行良好。这不包括对下一个版本会发生什么或 java 是否在新平台上运行的保证。此外,实际上将它们放在一起非常困难:您要么需要成为了解所有主要 VM 实现的所有详细信息的字典,要么需要完成工作并在大约 3 个操作系统中的每个操作系统上安装大约 15 个 JVM,在 30 种不同的硬件平台上,总共超过 1000 种组合,您需要在做出此类声明之前进行性能测试。

因此,鉴于以上是边缘性的精神错乱,您的问题的答案是“是”。

主要是因为这是任何形式问题的答案:

(任何事物)是否可以通过限制 JVM 至少在理论上能够以重要方式进行的优化来影响(任何事物)的性能?

是“是”。

一些可能有用的特定知识:

  • 如果关键字没有做任何有用的事情(例如,该字段仅被读取/写入为单线程或多线程访问在时间上间隔很远)。
  • 一般情况下,您不会为搞笑添加 volatile。你需要线程行为,所以你不能只比较有关键字和没有关键字的性能 - 没有关键字意味着代码被破坏,所以这显然是一种无用和不公平的比较。相反,您需要与下一个最佳替代方案进行比较,例如使用 AtomicX 或重写代码以提高线程之间的同步。
,

换句话说,VM 可以,至少在理论上,只能在 处理器缓存,并且仅在以下情况下进行实际内存分配 脸红...

真机一般没有这种能力。一个内存字有一个“地址”(在这个讨论中让我们忽略任何 MMU),这个地址标识这个字是在 CPU 缓存中还是在真实内存中。操作系统知道地址意味着它在某种意义上具有“分配的内存”。 CPU 写入内存。硬件可能现在或以后将其存储在缓存和/或内存中,具体取决于实现。

“不要从缓存写回”指令(在处理器初始化之外)并不常见。因此,CPU 没有办法阻止更改显示在内存中。它通常确实具有强制更改内存的方法; 'volatile' 告诉编译器这是需要的。

当然,JVM 是一个虚拟机,所以它可以为所欲为。但如果有一个不同于真实 CPU 缓存的“虚拟缓存”,我会感到非常惊讶。

进一步说明 - 操作系统通常具有分配零需求页面的机制,因此尽管虚拟内存存在,但在它被触摸之前不一定由页框支持,即“RAM”尚未“访问” .可以想象,在这种状态下可以部分创建一个大堆对象。但是,这与 CPU 缓存无关。

作为一个长期实践的程序员,我发现考虑“RAM”通常没有用,而是考虑“地址空间”和(虚拟)“内存”。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-