JVM-(10)JVM常见的一些问题

指令重排

什么是指令重排

CPU 为了提高指令执行效率,在执行某些耗时的指令(比如从内存中读取数据)时,会同时去执行其他与这条指令没有依赖关系的指令,使得原本的指令执行顺序改变

指令重排带来的问题

对于单线程而言指令重排几乎不会带来任何影响,因为指令重排的前提是保证串行语义执行的一致性,不能影响最终的结果,但对于多线程环境而言,指令重排就可能导致严重的程序轮序执行问题

如何禁止指令重排

使用 volatile 关键字

volatile 是如何禁止指令重排的

通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化

参考:https://baijiahao.baidu.com/s?id=1709086005694976168&wfr=spider&for=pc

synchronized 实现细节

public class SynChronizedDemo {

    void method(){
        synchronized (this){

        }
    }

    public static void main(String[] args) {

    }
}

通过 Jclasslib 工具查看 .class 解释后的指令:

 0 aload_0
 1 dup
 2 astore_1
 3 monitorenter
 4 aload_1
 5 monitorexit
 6 goto 14 (+8)
 9 astore_2
10 aload_1
11 monitorexit
12 aload_2
13 athrow
14 return

同一时刻 monitorenter monitorexit 之间的代码只允许一个线程访问

对象创建过程

  1. class loading :将 .class文件加载到内存
  2. class linking:
    • verfication : 核实.class文件是否符合JVM规范
    • preparation:给class静态变量赋默认值
    • resolution
  3. initializing:静态变量赋初始值
  4. 给对象申请内存
  5. 成员变量赋默认值
  6. 调用构造方法(init)
    • 多个成员变量按照顺序赋初始值
    • 执行构造方法语句

对象在内存中的存储布局


MarkWord:标记字段,用于存储对象锁信息(如锁状态,当前对象被哪个线程锁住)
对齐填充: CPU读取内存数据时按照8的倍数读取效率更高,如果对象存储长度不符合就填充

对象定位

T t = new T();

  • 句柄池
    实例对象引用和 T.class 对象引用放入句柄池中,引用 t 指向句柄池

  • 直接指针
    引用 t 指向实例对象,实例对象中有一个引用指向 T.class 对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值