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. Mybatis 枚举类处理

    目录 类型处理器(TypeHandler) 内置的枚举处理器 EnumTypeHandler源码 自定义枚举类处理 通用枚举处理器 Git 类型处理器(TypeHandler) 无论是 MyBatis ...

  2. java初探(1)之秒杀中的rabbitMQ

    rabbitMQ 消息队列,通过一定的通信协议,生产者和消费者在应用程序内传递通信. 主要的作用,提高负载,减耦合. 场景描述:当点击秒杀按钮的那个时刻,有很高的并发量,客户端发出请求之后,会判断库存 ...

  3. 【问题】Java和Scala混合编译下无法正常使用lombok的问题

    工作中有java和scala和混合编译的工程,最近遇到一个问题,就是工程中有依赖java bean的scala文件,编译过程中发现编译器无法找到Java bean 中 lombok生成的getter, ...

  4. <init>与<clinit>,static与final与static final

    <init>和<clinit> init是对象构造器方法,初始化对象的时候执行 clinit是类构造器方法,类加载的初始化阶段执行 final常量赋值(必须是一下其中一种) 显 ...

  5. Kubernetes K8S在IPVS代理模式下Service服务的ClusterIP类型访问失败处理

    Kubernetes K8S使用IPVS代理模式,当Service的类型为ClusterIP时,如何处理访问service却不能访问后端pod的情况. 背景现象 Kubernetes K8S使用IPV ...

  6. java-程序流程控制

    判断结构 if(条件){}; if(条件){} else{ }; if(条件){}else{};格式类似3目运算:int a=2,b;b=(a>5)?7:8;这种格式比较简便 if(条件){ } ...

  7. 2020年1月31日 安装Python的requests包记录

    C:\Users\ufo>pip install requests Collecting requests WARNING: Retrying (Retry(total=, connect=No ...

  8. fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached解决方法!

    UserAgent 就是用户代理,又叫报头,是一串字符串,相当于浏览器的身份证号,在利用爬虫爬取网站数据时,频繁更换它可以避免触发相应的反爬机制. fake-useragent对频繁更换UserAge ...

  9. Ant Jmeter Jenkins生成html测试报告

    Ant配置1. 将jmeter安装目录或者源码目录下\apache-jmeter-3.1\extras的ant-jmeter-1.1.1.jar复制到ant安装目录下apache-ant-1.10.3 ...

  10. Shader 001 - 函数造型能力

    0x00 从函数出发 Shader 中的很多效果都是由函数计算得出的,如何更好地理解二者的关系呢.不妨先看看函数是什么?函数的定义可以简单地描述为:给定一个集合 A,对于其中的元素施加法则 f,则可以 ...