面试题答案
一键面试对象在堆内存中的分配过程
- 对象创建:当使用
new
关键字创建一个对象时,Java 虚拟机(JVM)会在堆内存中为该对象分配内存空间。 - 内存分配策略:
- 指针碰撞:如果堆内存是规整的(已使用的内存和未使用的内存分别在一边),JVM 只需将指针向空闲内存方向移动与对象大小相等的距离,就完成了内存分配。
- 空闲列表:如果堆内存不规整,JVM 会维护一个记录空闲内存块的列表,分配内存时从列表中找到一块足够大的空闲空间分配给对象,并更新列表。
堆内存不同区域协同工作管理对象生命周期
- 新生代:
- 结构:新生代分为一个 Eden 区和两个 Survivor 区(一般称为 S0 和 S1)。
- 对象分配:新创建的对象通常首先分配在 Eden 区。
- 垃圾回收:当 Eden 区空间不足时,会触发 Minor GC(新生代垃圾回收)。此时,Eden 区和 Survivor 区中仍存活的对象会被复制到未使用的 Survivor 区(如 S1 区,假设之前在 S0 区),而 Eden 区和使用过的 Survivor 区(如 S0 区)中的垃圾对象会被回收。多次 Minor GC 后,仍存活的对象会被晋升到老年代。
- 老年代:
- 对象进入:经历多次 Minor GC 后仍然存活的对象,会被晋升到老年代。大对象(超过一定大小的对象)也可能直接分配到老年代。
- 垃圾回收:当老年代空间不足时,会触发 Major GC 或 Full GC(整堆垃圾回收),回收老年代中的垃圾对象。Full GC 通常比 Minor GC 更耗时,因为它需要扫描整个堆内存。
- 持久代(Java 8 之前)/元空间(Java 8 及之后):
- 持久代(Java 8 之前):存储类的元数据、常量池等信息。当持久代空间不足时,也可能触发 Full GC。
- 元空间(Java 8 及之后):元空间使用本地内存而不是堆内存,减少了由于持久代空间不足导致的 Full GC 频率。它同样存储类的元数据等信息。