java常见且经典面试问题收集
1、object o = new object();的o占中多少字节
如何查看对象内存分配:通过idea插件JOL来查看
- 对象头
- markword(8字节)
- 类型指针(默认开启压缩4字节,不开启压缩8字节)
- 实例数据(n字节)
- 对齐(保证对象可以被8字节整除的补齐字节数)
注:可以通过idea中的插件jol来查看对象的存储信息
答案:不开启压缩16字节(8+4+0+4),开启压缩16字节(8+8+0+0)
2、对象的创建过程
检查类是否已加载-》分配内存空间–》属性设置默认值–〉设置对象头–》执行构造方法
3、对象在内存中的存储分布
普通对象:对象头(mark work/class pointer)、对象实际数据(instance data)、对齐(padding)
数组:对象头(mark work/class pointer/length)、对象实际数据(instance data)、对齐(padding)
4、对象头具体包括什么
- Mark Word:8字节,存储对象hashcode、锁信息、分代年龄、GC信息等
- Class Pointer:4字节(默认开启压缩)/8字节类数据指针,用来确定这个对象属于哪个类
- Length:4字节,如果对象是数组则存在length用来确定数组长度
5、单例模式下DCL(double check locking双重校验锁)是否需要加volatile
懒汉式:获取的时候才创建
饿汉式:类加载的时候就创建
双重校验锁模式:
1 | public class Singleton7 { |
结论:当DCL模式下需要创建对象时,由于创建对象涉及到划分内存、赋默认值、执行构造方法等步骤,cpu有可能进行指令冲排序,所以需要volatile
参考资料:https://zhuanlan.zhihu.com/p/150004430
6、对象怎么定位即怎么找到对象
直接指针:指针指向堆对象,堆对象中的类型数据指针指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象
句柄方式:指针指向堆中的二元组,二元组记录实例数据指针(指向堆中的类实例)和类型数据指针(指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象)
7、对象怎么分配
- 是否可以创建在栈上(根据内存逃逸分析来判断),否则继续
- 是否足够大,足够大则存放在老年代
- 进行TLAB判断(线程本地分配缓存区),即是否可以分配到本线程在e区独享的区域
- GC回收后能够存活则进入survive区
- 多次GC回收后依然存活则进入老年代
8、为什么hotspot不实用c++对象来代表java对象
c++对象有虚表的概念,导致对象占用内存加大,不适合代表java对象
目前是用二元指针来代表java对象,记录实例数据指针(指向堆中的类实例)和类型数据指针(指向方法区的class对象)
9、class对象是在堆还是在方法区
放在堆
指针指向堆对象,堆对象中的类型数据指针指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!
本文出自:monkeyGeek
座右铭:生于忧患,死于安乐
欢迎志同道合的朋友一起交流、探讨!
monkeyGeek

