java常见面试问题

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton7 {
private static volatile Singleton7 instance = null;

private Singleton7() {}

public static Singleton7 getInstance() {
if (instance == null) {//不能去掉,否则会出现多线程竞争加锁
synchronized (Singleton7.class) {
if (instance == null) {//不能去掉,否则会创建多个对象
instance = new Singleton7();//此步骤借助volatile设置内存屏障避免读取到默认值
}
}
}
return instance;
}
}

结论:当DCL模式下需要创建对象时,由于创建对象涉及到划分内存、赋默认值、执行构造方法等步骤,cpu有可能进行指令冲排序,所以需要volatile

参考资料:https://zhuanlan.zhihu.com/p/150004430



6、对象怎么定位即怎么找到对象

直接指针:指针指向堆对象,堆对象中的类型数据指针指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象

句柄方式:指针指向堆中的二元组,二元组记录实例数据指针(指向堆中的类实例)和类型数据指针(指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象)



7、对象怎么分配

  1. 是否可以创建在栈上(根据内存逃逸分析来判断),否则继续
  2. 是否足够大,足够大则存放在老年代
  3. 进行TLAB判断(线程本地分配缓存区),即是否可以分配到本线程在e区独享的区域
  4. GC回收后能够存活则进入survive区
  5. 多次GC回收后依然存活则进入老年代


8、为什么hotspot不实用c++对象来代表java对象

c++对象有虚表的概念,导致对象占用内存加大,不适合代表java对象

目前是用二元指针来代表java对象,记录实例数据指针(指向堆中的类实例)和类型数据指针(指向方法区的class对象)



9、class对象是在堆还是在方法区

放在堆

指针指向堆对象,堆对象中的类型数据指针指向方法区的c++的class对象,在通过c++对象找到堆中的java class对象




版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!

本文出自:monkeyGeek

座右铭:生于忧患,死于安乐

欢迎志同道合的朋友一起交流、探讨!

monkeyGeek
#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×