JVM-面试题

一、对象

1、对象创建

  • 类加载检查
    • 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池定位到类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。若没有,必须先执行类加载过程。
  • 分配内存
    • 类加载检查通过后,jvm将为新生对象分配内存,对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。
      • 指针碰撞
        • 适合场景:堆内存规整(即没有内存碎片)的情况下
        • 原理:用过的内存全部整合到一边,没用过的放在另一边,中间有一个分界值指针,只需要向着没用过的内存方向将该指针移动对象内存大小位置即可:
        • GC收集器:Serial、ParNew
      • 空闲列表
        • 适合场景:堆内存不规整的情况下
        • 原理:JVM会维护一个列表,该列表中会记录哪些内存块是可用的,在分配的时候,找一块足够大的内存块来划分给对象实例,最后更新列表记录。
        • GC收集器:CMS
      • 并发的时候
        • 采用CAS 配上失败重试的方式保证更新操作的原子性
        • TLAB:为每一个线程预先在 Eden 区分配一块儿内存,JVM 在给线程中的对象分配内存时,首先在 TLAB 分配,当对象大于 TLAB 中的剩余内存或 TLAB 的内存己用尽时,再采用止述的 CAS 进行内存分配
  • 初始化零值
    • 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值 (不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不賦初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
  • 设置对象头
    • 初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。这些信息存放在对象头中。另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
  • 执行init()方法
    • 在上面工作都完成之后,从jvm的视角来看,一个新的对象已经产生了,但从Java 程序的视角来看,对象创建才刚开始,init方法还没有执行,所有的字段都还为零。所以一般来说,执行 new指令之后会接者执行init方法,把对象按照程序员的意愿进行初始化。

2、对象在内存的布局

  • 对象头:第一部分用于存储对象自身的运行时数据(哈希码、GC分代年龄、锁状态等),另一部分时类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
  • 实例数据:对象真正存储的有效信息,也是在程序中所定义的各种类型的字段内容
  • 对齐填充:仅仅起占位作用(Hotspot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍)

3、对象访问

  • 句柄:Java 堆中将会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息
  • 直接指针:reference 中存储的直接就是对象的地址(HotSpot)
    • 优点:句柄-reference 中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference 本身不需要修改。使用直接指针访问方式最大的好处就是速度快,它节省了一次指针定位的时问开销。

二、类加载

1、类加载器

  • 启动类加载器:最顶层的加载类,主要加载核心类库
  • 扩展类加载器:JDK的安装目录的lib/ext子目录下加载类库
  • 应用程序类加载器:负责加载环境变量classpath或系统属性java.class.path指定路径下的类库

2、双亲委派

  • 当一个类收到了类加载请求,它不会自己先去加载,而是把这个请求委派给父类加载器去完成,以此类推。只有当父类加载器无法完成这个加载请求时,子加载器才会尝试自己去加载。
  • 好处
    • 避免了类的重复加载,因为JVM中区分不同类的方式不仅仅是根据类名,还包括加载此类的类加载器。只有同一个类加载器加载的同一个类的两个实例才被认为是相同的
    • 保证了Java的核心API不被篡改,因为所有的类加载请求最终都会传递到顶层的启动类加载器中,而启动类加载器只加载核心类库,因此不可能被篡改。
  • 打破双亲委派机制
    • 自定义类加载器:通过继承java.lang.ClassLoader并重写loadClass方法
  • 23
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值