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_VOLATILE

  • JVM层面

    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】内存模型的更多相关文章

  1. 【JVM】JVM系列之内存模型(六)

    一.前言 经过前面的学习,我们终于进入了虚拟机最后一部分的学习,内存模型.理解内存模型对我们理解虚拟机.正确使用多线程编程提供很大帮助.下面开始正式学习. 二.Java并发基础 在并发编程中存在两个关 ...

  2. JVM学习笔记——内存模型篇

    JVM学习笔记--内存模型篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存模型部分 我们会分为以下几部分进行介绍: 内存模型 乐观锁与悲观锁 synchronized优化 内 ...

  3. [转帖]JVM—深入理解内存模型与垃圾收集机制

    JVM—深入理解内存模型与垃圾收集机制 https://juejin.im/post/5d68dc9ee51d4561ad6548f7 前言 Java是一种跨平台的语言,当初其设计初衷也是为了解决各个 ...

  4. (转载)JVM中的内存模型与垃圾回收

    转载自微信公众号:Java高级架构(Java-jiagou)-----看完这篇文章,我奶奶都知道JVM中的内存模型与垃圾回收了! 六.内存模型 6.1  内存模型与运行时数据区 Java虚拟机在执行J ...

  5. JVM学习--(二)内存模型、可见性、指令重排序

    我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存模型 首先我们思考一下一个java线程要向另外一个线程进行通信,应该怎么做,我们再 ...

  6. 深入理解JVM(6)——Java内存模型和线程

    Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...

  7. 【JVM】Java内存模型

    原文:多线程之Java内存模型(JMM)(一) 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per S ...

  8. jvm(12)-java内存模型与线程

    [0]README 0.1)本文部分文字描述转自“深入理解jvm”,旨在学习“java内存模型与线程” 的基础知识:   [1]概述 1)并发处理的广泛应用是使得 Amdahl 定律代替摩尔定律称为计 ...

  9. 看完这篇文章,我奶奶都知道什么是JVM中的内存模型与垃圾回收!

    扩展阅读:JVM从入门开始深入每一个底层细节 六.内存模型 6.1.内存模型与运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同数据区域. Java内存模型的主要目 ...

  10. JVM总结-java内存模型

    我们先来看一个反常识的例子. int a=0, b=0; public void method1() { int r2 = a; b = 1; } public void method2() { in ...

随机推荐

  1. Go测试开发(一) 怎么写Go代码

    安装过程略过,网上搜一大把. 介绍 本文会在一个module中开发一个简单的Go package. 同时介绍go tool(也就是go命令行). 以及如何fetch,build和install Go的 ...

  2. Currency Exchange(SPFA判负环)

    Several currency exchange points are working in our city. Let us suppose that each point specializes ...

  3. Funny Positive Sequence (思维+前缀)

    There are n integers a 1,a 2,…,a n-1,a n in the sequence A, the sum of these n integers is larger th ...

  4. 非构造函数方式创建DbContext实例的方法

    using Microsoft.EntityFrameworkCore;using Microsoft.EntityFrameworkCore.Design;using Microsoft.Entit ...

  5. 软件定义网络实验(一)----Mininet源码安装和可视化拓扑工具

    一.实验任务 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具. 二.实验任务 使用源码安装 Mininet 的 2.3.0d6 版本,并使用可视化拓扑工具生成一个最简拓扑 ...

  6. python:接口开发

    一.flask flask是一个python编写的轻量级框架,可以使用它实现一个网站或者web服务.本文就用flask来开发一个接口. flask需要先安装再引用.pip install flask ...

  7. 【NOIP2013模拟】黑魔法师之门

    题目描述 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Violet星球. ...

  8. Kafka 【入门一篇文章就够了】

    初识 Kafka 什么是 kafka Kafka 是由 Linkedin 公司开发的,它是一个分布式的,支持多分区.多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的基于发布订 ...

  9. 升级微服务架构5:API网关

    API网关是一个服务器,是系统的唯一入口.从面向对象设计的角度看,它与外观模式类似.API网关封装了系统内部架构,为每个客户端提供一个定制的API.它可能还具有其它职责,如身份验证.监控.负载均衡.缓 ...

  10. Docker实战(2):主从库搭建

    入门 基于Docker的Mysql主从复制搭建 首先安装docker 拉取mysql镜像:5.7版本 启动主从数据库容器 docker run -p 3339:3306 --name Maste -e ...