美团夺命九问

美团夺命九问

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

  1. 在堆中为对象分配空间,给成员变量赋上默认值
  2. 执行初始化init方法,给成员变量赋初始值
  3. 建立变量和对象实际地址的引用关系

DCL要不要加volatile问题?

要加,因为会产生指令重排问题,如果发生了指令重排,那么拿到的对象可能就不是单例了

对象在内存中的存储布局?

image

对象头具体包括什么?

  1. markword:包含与对象相关的信息,锁信息,hashcode信息,GC信息等等
  2. klass pointer:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例

对象怎么定位?

直接、间接

直接:直接将对象的地址赋值给引用变量,这种方式在GC的时候可能涉及地址的变更

对象怎么分配?

  1. 首先会尝试在上分配对象,如果这个兑现在栈帧结束之后就不被使用的话,就可以在栈上分配,栈帧结束之后直接pop对象也就死亡了,就不用GC了
  2. 如果是大对象的话,直接在老年代创建
  3. 尝试在Thread Local Allocation Buffer上分配。堆是所有的线程共有的,那么在分配对象空间时,就会有先来后到的问题,也就是线程同步问题。java就给每一个线程在堆上分配了一个Thread Local Allocation Buffer线程先考虑在这款内存空间中分配
  4. 尝试在新生代中的Eden中分配
  5. 如果对象经历了好多次GC依然存活,就会移动到老年代

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

8字节的markword + 4字节的klasspointer + 4字节的补齐 = 16字节

为什么hotspot不使用C++对象代表Java对象?

C++对象中有用于实现多态的虚方法表,比较占空间。

Java的实现初衷就是紧凑,java主要做的是网络传输,以前的网络带宽不大,所以要紧凑一点

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

堆上

JVM会每个类在方法区上存储一些信息

image.png

jvm为每个加载的类都创建一个java.lang.Class的实例(存储在堆上)。而jvm必须以某种方式把Class的这个实例和存储在方法区中的类型数据(类的元数据)联系起来, 因此,类的元数据里面保存了一个Class对象的引用(class实例的引用);

而对象头中的kclasspointer其实指向的是Class对象。

posted @ 2023-05-05 12:22  Sstarry  阅读(10)  评论(0)    收藏  举报