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之前的写入操作,其更新的数据对于其它线程也是可见的
Java 内存模型和硬件内存架构笔记的更多相关文章
- 【Java虚拟机4】Java内存模型(硬件层面的并发优化基础知识--缓存一致性问题)
前言 今天学习了Java内存模型第一课的视频,讲了硬件层面的知识,还是和大学时一样,醍醐灌顶.老师讲得太好了. Java内存模型,感觉以前学得比较抽象.很繁杂,抽象. 这次试着系统一点跟着2个老师学习 ...
- Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系
CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...
- Java内存模型与线程_学习笔记
深入理解java虚拟机: 1.java内存模型 java虚拟机规范中试图定义一种Java内存模型.Java Memory Model(JMM) 1.1 主内存与工作内存 java内存模型规定所有的变量 ...
- 【java】java内存模型(2)--volatile内存语义详解
多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”.可见性的意思是当一个线程 ...
- Java内存模型-volatile的内存语义
一 引言 听说在Java 5之前volatile关键字备受争议,所以本文也不讨论1.5版本之前的volatile.本文主要针对1.5后即JSR-133针对volatile做了强化后的了解. 二 vol ...
- JAVA内存模型与JVM内存结构
问题:什么事java内存模型? 首先呢不要答堆.栈.方法区.这是JVM的内存结构.下面阐述了JMM和JVM的区别和自己对JMM的见解 1.Java内存模型(JMM):即多线程相关的.定义了一个线程对另 ...
- Java内存模型、JVM内存结构和Java对象模型
JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存 ...
- 04-JVM内存模型:直接内存
1.1.什么是直接内存(Derect Memory) 在内存模型最开始的章节中,我们画出了JVM的内存模型,里面并不包含直接内存,也就是说这块内存区域并不是JVM运行时数据区的一部分,但它却会被频繁的 ...
- 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈
C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...
随机推荐
- yarn组件通信协议简介
ResourceManager与NodeManager通过ResourceTracker协议通信. NodeManager通过NodeStatusUpdaterImpl中的ResourceTracke ...
- @vue/cli 构建得项目eslint配置2
使用ESLint+Prettier来统一前端代码风格 加分号还是不加分号?tab还是空格?你还在为代码风格与同事争论得面红耳赤吗? 正文之前,先看个段子放松一下: 去死吧!你这个异教徒! 想起自己刚入 ...
- 运维笔记--ubuntu管理启动项
启动项 https://blog.csdn.net/sz457763638/article/details/78182700
- HPE服务器做raid5阵列
HPE服务器做阵列的详细步骤: 注意:HPE服务器加硬盘需要安装配套的扩展笼~~~ 1.首先服务器开机,出现下图界面按F10. 2.然后在下图中选择HPE interlligent Provision ...
- ZOJ Problem Set - 2397 Tian Ji -- The Horse Racing
#include<iostream> #include<cmath> #include<algorithm> #define REP(i,n) for(int i= ...
- web.xml配置web中的key points(下)
一.配置jsp页面 [jsp-config]中有两个子元素[taglib][jsp-property-group],注意,前者必须出现在后者之前. ①[taglib]替代jsp页面中taglib指令 ...
- leetcode — rotate-image
import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/rotate-image/ * * Created b ...
- 使用Laya引擎开发微信小游戏(上)
本文由云+社区发表 使用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏. 作者:马晓东,腾讯前端高级工程师. 微信小游戏的推出也快一年时间了,在IEG的游戏运营活动中,也出现 ...
- CentOS docker 常用命令
yum install docker 安装服务 systemctl start docker.service 启动服务 systemctl enable docker.service 开机启动服务 d ...
- python元组类型
元组类型简介 使用括号包围的数据结构是元组(tuple).例如: >>> (1,2,3) (1, 2, 3) >>> T = (1,2,3,) >>&g ...