美团夺命九问
美团夺命九问
请解释一下对象的创建过程(半初始化)?
- 在堆中为对象分配空间,给成员变量赋上默认值
- 执行初始化init方法,给成员变量赋初始值
- 建立变量和对象实际地址的引用关系
DCL要不要加volatile问题?
要加,因为会产生指令重排问题,如果发生了指令重排,那么拿到的对象可能就不是单例了
对象在内存中的存储布局?
对象头具体包括什么?
- markword:包含与对象相关的信息,锁信息,hashcode信息,GC信息等等
- klass pointer:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
对象怎么定位?
直接、间接
直接:直接将对象的地址赋值给引用变量,这种方式在GC的时候可能涉及地址的变更
对象怎么分配?
- 首先会尝试在
栈上分配对象,如果这个兑现在栈帧结束之后就不被使用的话,就可以在栈上分配,栈帧结束之后直接pop对象也就死亡了,就不用GC了 - 如果是大对象的话,直接在老年代创建
- 尝试在
Thread Local Allocation Buffer上分配。堆是所有的线程共有的,那么在分配对象空间时,就会有先来后到的问题,也就是线程同步问题。java就给每一个线程在堆上分配了一个Thread Local Allocation Buffer线程先考虑在这款内存空间中分配 - 尝试在新生代中的Eden中分配
- 如果对象经历了好多次GC依然存活,就会移动到老年代
Object o = new Object()在内存中占用多少字节?
8字节的markword + 4字节的klasspointer + 4字节的补齐 = 16字节
为什么hotspot不使用C++对象代表Java对象?
C++对象中有用于实现多态的虚方法表,比较占空间。
Java的实现初衷就是紧凑,java主要做的是网络传输,以前的网络带宽不大,所以要紧凑一点
Class对象是在堆还是在方法区?
堆上
JVM会每个类在方法区上存储一些信息
jvm为每个加载的类都创建一个java.lang.Class的实例(存储在堆上)。而jvm必须以某种方式把Class的这个实例和存储在方法区中的类型数据(类的元数据)联系起来, 因此,类的元数据里面保存了一个Class对象的引用(class实例的引用);
而对象头中的kclasspointer其实指向的是Class对象。

浙公网安备 33010602011771号