JVM底层部分面试题

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

  • 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模型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章