MST

星途 面试题库

面试题:Java垃圾回收机制下的分代收集策略

在Java的分代收集垃圾回收策略中,为什么要将堆内存分为新生代、老年代和永久代(Java 8之前)?它们的垃圾回收方式有何不同?新生代又为何要进一步细分为Eden区和Survivor区,这样划分有什么好处?
12.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

堆内存分区原因

  1. 新生代:大多数对象在创建后很快就不再被使用,将它们集中在新生代可以更高效地进行垃圾回收,避免对整个堆进行频繁扫描。
  2. 老年代:经历多次垃圾回收仍然存活的对象会被移到老年代。老年代的对象存活率较高,采用不同的回收策略可以提高回收效率,减少对应用程序的影响。
  3. 永久代(Java 8之前):用于存储类的元数据、常量等信息,与其他代分开管理有助于对这些数据进行单独的垃圾回收和内存管理。

垃圾回收方式不同

  1. 新生代:采用复制算法。因为新生代对象存活时间短,复制少量存活对象到Survivor区,然后清空Eden区和原Survivor区,这种方式简单高效。
  2. 老年代:一般采用标记 - 整理算法或标记 - 清除算法。由于老年代对象存活率高,复制算法开销大,标记 - 整理算法可以在标记存活对象后,将存活对象整理到一端,然后清理另一端的空间;标记 - 清除算法则是标记存活对象,直接清除未标记对象,但会产生内存碎片。
  3. 永久代(Java 8之前):主要回收废弃常量和无用的类。当类加载器不再存活,相关的类元数据等就可以被回收,回收方式与老年代类似。

新生代细分原因及好处

  1. 进一步细分原因:为了更好地管理新生代对象的生命周期,提高垃圾回收效率。
  2. 好处
    • 提高回收效率:Eden区用于新对象的分配,大部分对象在Eden区很快就会被回收,减少了对老年代的影响。Survivor区作为对象从新生代到老年代的过渡区域,通过复制算法,将存活对象在两个Survivor区之间复制,经过多次复制仍存活的对象进入老年代,这种方式可以有效筛选出长寿对象,避免频繁在新生代和老年代之间移动对象。
    • 减少内存碎片:复制算法在Eden区和Survivor区使用,每次回收都能整理内存,减少内存碎片的产生,使得内存分配更加高效。