Java 内存模型和硬件内存架构笔记
前言
可跟《主存存取和磁盘存取原理笔记》串着看
https://blog.csdn.net/suifeng3051/article/details/52611310
杂技
Java 内存模型(堆栈)
Jvm 内部,Java 内存模型把内存分成了两个部分:线程栈区和堆区:
栈区包含:线程执行信息(线程栈),本地原始类型变量(boolean,byte, short, int, long, float, double)
堆区包含:Java 应用创建的所有对象信息,基础类型的封装类
- 一个本地变量如果是原始类型,存储栈中
- 一个本地变量是一个对象的引用,那么这个本地引用存储栈,对象本身存储堆中
- 一个对象的成员方法,存储栈中,方法中包含的原始类型变量,存储堆中
- 一个对象的成员变量,无论是原始类型还是包装类型,都存储堆中
- 堆中数据可被多个线程共享,对于原始类型变量,每个线程都会拷贝一份
硬件内存架构
不管什么内存模型,最终还是运行在计算机硬件上,因此有必要了解计算机硬件的内存架构
- 现在计算机一般都有2个以上cpu, 每个cpu还有多个核心,线程会在各个cpu核心中并行运行
- CPU 内部会有一组CPU 寄存器、CPU 缓存(一级,二级,三级缓存),RAM主存
- 存储速度: CPU 寄存器 > CPU 缓存(一级> 二级> 三级) > RAM
- 存储大小 CPU 寄存器(64 bit) < CPU 缓存[一级(64k)> 二级(256k)> 三级(8MB)] < RAM(4G)
线程间的竞争现象
- 存在 count 为1, 两个线程都在缓存中保存一份备份
- 两个线程分别改变 count 的值,存在写缓存,顾缓存和 RAM的值存在偏差
- 当写缓存的数据 flush 到 RAM 就发生冲突了
内存屏障(Memory Barrier):
- 内存屏障,又称内存栅栏,是一个CPU 指令
- 保证特定操作的执行顺序。编译器和CPU会重排序指令,为了优化,插入内存屏障指令会让CPU不把这条指令重排序。
- 影响某些数据(或某条指令的执行结果)的内存可见性。强制刷新各种CPU cache, 写缓存的数据直接写入RAM,读缓存重新读取数据
内存屏障和 Java 有什么关系?
volatile 是基于 Memory Barrier 实现的。
这意味着,如果写入一个 volatile 变量a,可以保证:
- 一个线程写入变量a 后,任何线程访问该变量都会拿到最新值
- 由于会刷新 Cache中所有先前写入,因此写入变量a之前的写入操作,其更新的数据对于其它线程也是可见的
作者:但,我知道
出处:http://www.cnblogs.com/haichao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架