JVM

    科技2025-04-13  16

    文章目录

    解释一下对象的创建过程(半初始化)DCL单例到底需不需要加volatile?(单例模式,指令重排)对象在内存中的存储布局(对象和数组的存储不同)对象头包括什么?(Markword,class pointer)对象怎么定位?(直接、间接)对象怎么分配?(栈上-线程本地-Edum-Old)Object o = new Object()在内存中占多少个字节?为什么hotspot不使用c++对象来代表java对象?Class对象是在堆还是方法区?

    解释一下对象的创建过程(半初始化)

    Object o = new Object();

    new Object()先在内存中申请空间,创建出对象,半初始化;o在main方法栈帧中产生,存放堆中对象的内存地址;最后指针指向堆对象,建立关联。

    详细参考:图解JAVA对象的创建过程

    DCL单例到底需不需要加volatile?(单例模式,指令重排)

    DCL:double check lock双重检测锁;用volatile修饰的对象,会禁止对该对象存储位置操作的指令重排。通过问题一我们知道对象创建分为三个步骤,这三个步骤之间有可能会发生指令重排。多线程条件下,一个线程操作对象:执行完半初始化,下一步可能会先建立连接再执行对象的init方法,另一个线程可能会在对象建立完连接便提取对象,此时对象处于半初始化状态。volatile:禁止指令重排,会避免使用到半初始化状态的对象。

    对象在内存中的存储布局(对象和数组的存储不同)

    对象头包括什么?(Markword,class pointer)

    markword:hashcode、gc、锁信息(读hotspot源码)(8个字节)class pointer 指向类对象(开启压缩4个字节,不压缩8个字节)

    对象怎么定位?(直接、间接)

    hotsopot的具体实现,实现方式是直接指针。

    句柄(间接)方式:方便gc操作,GC需要经常移动对象。

    对象怎么分配?(栈上-线程本地-Edum-Old)

    jvm读到new关键字,首先会尝试在栈上分配对象(经过逃逸分析和标量替换),栈上创建对象的好处:栈内对象出栈之后,生命周期结束,不需要GC介入。。TLAB:thread local allcation buffer 线程本地分配缓冲区,管理线程的分配竞争。

    Object o = new Object()在内存中占多少个字节?

    =右边:

    class pointer: 指向类对象(开启压缩4个字节,不压缩8个字节)

    markword:hashcode、gc、锁信息(读hotspot源码)(8个字节)

    instance data:按数据量变化,没有则为0字节

    最后对齐(被8整除)

    =左边:

    o也占用空间,压缩4个字节,不压缩8个字节。

    为什么hotspot不使用c++对象来代表java对象?

    vritual pointer虚函数表的指针在c++有,在java没有。

    Class对象是在堆还是方法区?

    对象的创建与OOP-Klass模型

    Processed: 0.008, SQL: 8