Java 垃圾回收(Garbage Collection, GC)主要有以下几种实现方式,不同的垃圾收集器采用了不同的回收策略:
-
标记-清除算法(Mark-Sweep)
- 分为"标记"和"清除"两个阶段:先标记出所有需要回收的对象,然后统一回收这些对象
- 缺点:会产生内存碎片,可能导致后续无法为大对象分配连续内存
-
标记-复制算法(Mark-Copy)
- 将内存分为大小相等的两块,每次只使用其中一块
- 标记出存活对象后,将其复制到另一块内存,然后清除当前块的所有对象
- 优点:解决了内存碎片问题;缺点:内存利用率低(仅50%)
- 典型应用:新生代的Serial GC、ParNew GC
-
标记-整理算法(Mark-Compact)
- 标记出存活对象后,将所有存活对象向内存空间的一端移动,然后清除边界以外的内存
- 优点:既避免内存碎片,又提高内存利用率;缺点:移动对象需要额外开销
- 典型应用:老年代的垃圾收集器
-
分代收集算法(Generational Collection)
- 根据对象的存活周期将内存划分为不同区域(新生代、老年代等)
- 新生代:对象存活时间短,采用标记-复制算法
- 老年代:对象存活时间长,采用标记-清除或标记-整理算法
- 这是当前主流JVM采用的垃圾回收思想,如HotSpot虚拟机
实际应用中,Java虚拟机(如HotSpot)提供了多种基于上述算法的垃圾收集器,如Serial GC、Parallel GC、CMS、G1、ZGC、Shenandoah等,它们在吞吐量、延迟等方面各有侧重,适用于不同的应用场景。