JVM系列【4】内存模型
JVM系列笔记目录
- 虚拟机的基础概念
- class文件结构
- class文件加载过程
- jvm内存模型
- JVM常用指令
- GC与调优
硬件层数据一致性
- 存储器层次结构
从L6-L0 空间由大变小,速度由慢到快。
-缓存一致性算法
CPU实现缓存一致性的协议很多,其中intel 使用的MESI(Modified Exclusive Shared Or Invalid)协议。具体可以参考:[MESI--CPU缓存一致性协议](https://www.cnblogs.com/z00377750/p/9180644.html)
现代CPU的数据一致性实现=缓存锁(MESI...) +总线锁
-缓存行
缓存读取时的单位,一般是64Byte
使用缓存行的对齐能够提高效率
-伪共享
位于同一缓存行的2个不同的数据,被2个不同的CPU锁定,产生互相影响的伪共享问题。
如何解决? 使用缓存行的对齐能够提高效率
CPU乱序问题
- 概念
CPU为了提高执行效率,会在一条指令执行的过程中(比如去内存取数据(慢100倍)),去同时执行另一条指令,前提是两条指令没有依赖关系。具体参考:[现代cpu的合并写技术对程序的影响](https://www.cnblogs.com/liushaodong/p/4777308.html)
-合并写
CPU上有一个WriteCombinBuffer,仅4个字节,比L1等级还高,某些写操作会合并在一起提交。[现代cpu的合并写技术对程序的影响](https://www.cnblogs.com/liushaodong/p/4777308.html)
-乱序证明
CPU乱序现象有大佬写程序模拟出来了,具体参考: Memory Reordering Caught in the Act
如何保证在特定情况下保证不乱序
硬件级别
X86 CPU级别内存屏障
sfence
store fence 在sfence指令前的写操作必须在sfence指令后的写操作前完成lfence
load fence 在lfence指令前的读操作必须在lfence指令后的读操作前完成mfence
mixed fence 在mfence指令前的读写操作必须在mfence指令后的读写操作前完成CPU原子指令
如x86上的”lock …” 指令是一个Full Barrier,执行时会锁住内存子系统来确保执行顺序,甚至跨多个CPU总结: Software Locks通常使用了内存屏障或原子指令来实现变量可见性和保持程序顺序
JVM级别
JSR113规范规定了4种内存屏障
LoadLoad屏障
对于语句Load1;LoadLoad;Load2,在Load2及后续读取指令要读取的数据被访问前,保证Load1要读取的数据被读取完毕StoreStore屏障
对于语句Store1;StoreStore;Store2,在Store2及后续写操作执行前,保证Store1的写入操作对其它处理器可见LoadStore屏障
对于语句Load1;StoreStore;Store2,在Store2及后续写操作被刷出前,保证Load1要读取的数据被读取完毕StoreLoad屏障
对于语句Store1;StoreStore;Load2,在Load2及后续读取指令要执行前,保证Store1的写入操作对其它处理器可见
sychronized/volatile在字节码、JVM、硬件OS层面实现细节
- sychronized
字节码层面
sychronized m() : AccessFlag : ACC_VOLATILE
sychronized(this){} : monitorenter monitorexit monitorenter
JVM层面
C/C++ 调用操作系统的同步操作
硬件OS层面
X86 : lock cmpxchg / xxx
-volatile
字节码层面
AccessFlag : ACC_VOLATILEJVM层面
volatile内存区域都加屏障
StoreStoreBarrier volatile 写操作 StoreLoadBarrier
LoadLoadBarrier volatile 读操作 LoadStoreBarrier
硬件OS层面
windows lock 指令实现 或是 MESI实现
面试new Object() 6连问
1.解释对象的创建过程
该问题结合上篇博客:JVM系列【3】Class文件加载过程不难回答出来。
class loading
class linking (vertification prepraration resolution)
class initiazing
new 申请内存空间
成员变量赋初始值
调用构造方法:成员变量赋初始值;执行构造方法语句,super()父类构造。
2.对象在内存中的存储布局
对象在内存中布局分普通对象和数组对象。
普通对象4部分:对象头markword(8字节)、ClassPointer指针(4或8字节)、实例数据、padding对齐为8的倍数。
数组对象5部分,和普通对象类似,但中间是数组长度4字节和具体的数组数据。
3.对象头具体包括什么
对象头markword(8字节)具体内容和对象锁状态有关系,其中最高位2位是锁状态中,最低3位用作锁标志位,中间4位是GC年龄,如下。
4.对象怎么定位
通过句柄池和直接指针,具体参考:访问对象两种方式--句柄和直接指针
5.对象怎么分配?
对象的分配其实和垃圾回收GC有关系,后续总结GC详细讲。
6.Object o = new Object() 在内存中的占用多少个字节
16个字节,根据第2点的内存布局可以算出。
知识分享,转载请注明出处。学无先后,达者为先!
JVM系列【4】内存模型的更多相关文章
- 【JVM】JVM系列之内存模型(六)
一.前言 经过前面的学习,我们终于进入了虚拟机最后一部分的学习,内存模型.理解内存模型对我们理解虚拟机.正确使用多线程编程提供很大帮助.下面开始正式学习. 二.Java并发基础 在并发编程中存在两个关 ...
- JVM学习笔记——内存模型篇
JVM学习笔记--内存模型篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存模型部分 我们会分为以下几部分进行介绍: 内存模型 乐观锁与悲观锁 synchronized优化 内 ...
- [转帖]JVM—深入理解内存模型与垃圾收集机制
JVM—深入理解内存模型与垃圾收集机制 https://juejin.im/post/5d68dc9ee51d4561ad6548f7 前言 Java是一种跨平台的语言,当初其设计初衷也是为了解决各个 ...
- (转载)JVM中的内存模型与垃圾回收
转载自微信公众号:Java高级架构(Java-jiagou)-----看完这篇文章,我奶奶都知道JVM中的内存模型与垃圾回收了! 六.内存模型 6.1 内存模型与运行时数据区 Java虚拟机在执行J ...
- JVM学习--(二)内存模型、可见性、指令重排序
我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...
- 深入理解JVM(6)——Java内存模型和线程
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...
- 【JVM】Java内存模型
原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...
- jvm(12)-java内存模型与线程
[0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识: [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计 ...
- 看完这篇文章,我奶奶都知道什么是JVM中的内存模型与垃圾回收!
扩展阅读:JVM从入门开始深入每一个底层细节 六.内存模型 6.1.内存模型与运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同数据区域. Java内存模型的主要目 ...
- JVM总结-java内存模型
我们先来看一个反常识的例子. int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { in ...
随机推荐
- Mac 安装多个版本jdk
JDK默认安装路径为/Library/Java/JavaVirtualMachines 多版本安装后效果为: 设置 1.执行以下命令 cd ~ open -e .bash_profile #打开.ba ...
- 1.OpenGL mac开发环境搭建记录
1.安装GLEW 和GLFW,转摘至:https://www.cnblogs.com/pretty-guy/p/11357793.html 2.开始测试,整个工程报错,关键信息如下: code sig ...
- Unity 打AssetBundle和加载方案
一.如何组织assetBundle: unity5以前,打包需要自己去找依赖,然后需要按照拓扑图顺序压入AB栈,这样在最后打AB时才能有效利用依赖(栈内已有的AB才能作为依赖). unity5.x后, ...
- Web测试和前端技术
Html Form表单 用户需要输入内容的地方一般有一个表单元素 method:GET/POST action:要打开/提交的目文件 Table表格 检查表格数据和数据库的一致性 表格的布局检测:填满 ...
- 原生JDK网络编程- NIO之Reactor模式
“反应”器名字中”反应“的由来: “反应”即“倒置”,“控制逆转”,具体事件处理程序不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣,有时间来了,具体事件处理程序通过事件处理器对某 ...
- Apache Nginx Tomcat
Tomcat Tomcat:动态解析容器 处理动态请求,是编译JSP/Servlet的容器 区别: 严格意义上来说 Apache和nginx应该叫做HTTP Server tomcat是一个Appli ...
- J2EE之JavaScript(1)
声明:此博客仅供记录自己的学习记录和随笔,看看就行了,就图一乐! 本篇学习随笔来自JavaScript 菜鸟教程:https://www.runoob.com/js/js-howto.html J ...
- 读书笔记 | Kubernetes in Action
1 Kubernetes介绍 Kubernetes(以下简称K8s) 是一个部署和管理容器化应用的软件系统.它将底层基础设施抽象,简化了应用的开发.部署,以及对开发和运维团队的管理. K8s由一个主节 ...
- TKE基于弹性网卡直连Pod的网络负载均衡
前言 Kubernetes在集群接入层设计并提供了两种原生资源Service和Ingress,分别负责四层和七层的网络接入层配置. 传统的做法是创建Ingress或LoadBalancer类型的Ser ...
- Spring Boot 启动第一个页面(Spring二)
在前面的文章里我配置好了spring boot的环境,并选择STS开发工具 具体文章见:https://blog.csdn.net/qq_38175040/article/details/105481 ...