JVM系列笔记目录

  • 虚拟机的根底概念
  • class文件构造
  • class文件加载过程
  • jvm内存模型
  • JVM罕用指令
  • GC与调优

硬件层数据一致性

- 存储器层次结构

从L6-L0 空间由大变小,速度由慢到快。

-缓存一致性算法

CPU实现缓存一致性的协定很多,其中intel 应用的MESI(Modified Exclusive Shared Or Invalid)协定。具体能够参考:[MESI--CPU缓存一致性协定](https://www.cnblogs.com/z0037...

古代CPU的数据一致性实现=缓存锁(MESI...) +总线锁

-缓存行

缓存读取时的单位,个别是64Byte
应用缓存行的对齐可能提高效率

-伪共享

位于同一缓存行的2个不同的数据,被2个不同的CPU锁定,产生相互影响的伪共享问题。

如何解决? 应用缓存行的对齐可能提高效率

CPU乱序问题

- 概念

CPU为了进步执行效率,会在一条指令执行的过程中(比方去内存取数据(慢100倍)),去同时执行另一条指令,前提是两条指令没有依赖关系。具体参考:[古代cpu的合并写技术对程序的影响](https://www.cnblogs.com/liush...

-合并写

CPU上有一个WriteCombinBuffer,仅4个字节,比L1等级还高,某些写操作会合并在一起提交。[古代cpu的合并写技术对程序的影响](https://www.cnblogs.com/liush...

-乱序证实

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 申请内存空间

    成员变量赋初始值

    调用构造方法<init>:成员变量赋初始值;执行构造方法语句,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点的内存布局能够算出。

常识分享,转载请注明出处。学无先后,达者为先!