JVM 垃圾回收算法

Heer Liu

与其他语言相比,Java有着自动内存管理的优势,即由JVM自动进行内存分配和垃圾回收处理。本篇博客将介绍JVM中的垃圾回收算法。

垃圾回收的基本概念

垃圾回收的目的是释放无用的内存空间以供后续的内存分配使用。JVM中使用垃圾回收器(Garbage Collector)来自动实现这个过程。垃圾回收器会在发现内存中存在无用的对象时,将其所占用的内存空间回收。

为了实现垃圾回收,需要定义什么是“无用对象”。在JVM中,一个对象被判定为无用对象,当且仅当它满足下列条件:

  • 该对象没有被引用
  • 该对象的所有引用均已断开

垃圾回收算法的目标是尽可能快地识别和回收无用对象,同时保持系统性能的稳定。

常见垃圾回收算法

标记-清除算法

标记清楚

标记-清除算法是最基本的垃圾回收算法。它分为两个阶段:标记和清除。

在标记阶段,垃圾回收器遍历堆中的所有对象,并标记出所有被引用的对象。在清除阶段,垃圾回收器将未被标记的对象所占用的内存空间全部回收。

这个算法的缺点是会产生碎片,因为回收后的内存空间是不连续的。如果始终使用标记-清除算法,那么随着时间的推移,内存空间中的空洞(即碎片)将越来越多,导致内存分配效率降低。

复制算法

复制算法

复制算法是一种高效的垃圾回收算法。它将堆空间划分为大小相等的两块,每次只使用其中一块。当这一块内存空间用完时,垃圾回收器将已经标记了的存活对象复制到另一块未使用的空间中,然后清除已使用的那一块空间并交换它们的角色。

复制算法的缺点是需要消耗一半的空间。同时,如果存活对象很多,每次都要进行复制操作,也会带来不小的性能开销。

标记-整理算法

整理算法

标记-整理算法是对标记-清除算法的改进。它同样分为两个阶段:标记和整理。

在标记阶段,垃圾回收器遍历堆中的所有对象,并标记出所有被引用的对象。在整理阶段,垃圾回收器将所有存活对象移到堆的一端,然后清除堆的另外一端上的所有无用对象。

标记-整理算法通过整理过程来解决标记-清除算法产生的碎片问题,使得内存空间变得连续起来。

三色标记

三色标记是一种用于 Java 虚拟机(JVM)垃圾回收算法的技术,配合可达性分析算法实现垃圾的高效、准确的收集。

在三色标记中,JVM将内存对象分为三个不同的颜色:白色、灰色和黑色。

  • 白色:表示对象尚未被扫描和标记。
  • 灰色:表示对象已经被扫描,但是它引用的其他对象尚未被扫描和标记。
  • 黑色:表示对象已经被扫描和标记,并且它引用的其他对象也已经被扫描和标记。

JVM 使用三色标记来跟踪哪些对象可以被安全地回收。当 JVM 进行垃圾回收时,它会从根对象开始遍历所有对象,并将它们标记为灰色或黑色。然后,JVM 会清除所有白色对象,因为这些对象没有任何引用。

在三色标记算法中,灰色的对象表示悬挂的对象,即其引用的对象尚未被处理。如果某个对象的所有引用都已经被扫描和标记,那么它就会被标记为黑色。

通过使用三色标记算法,JVM 可以更快地确定哪些对象可以被安全地回收,从而提高了应用程序的性能和可靠性。

分代收集算法

分代收集算法是目前主流的垃圾回收算法。它根据对象的存活周期把堆区域分为新生代和老年代两个区域。新生代中的对象通常存活时间较短,而老年代中的对象则存活时间较长。不同区域采用不同的垃圾回收算法。

新生代通常使用复制算法。它把新生代分为Eden区和两个Survivor区,每次只使用Eden区和其中一个Survivor区,将已经标记了的存活对象复制到另一块未使用的Survivor区中,然后清除Eden区和已使用的Survivor区中的无用对象。

老年代通常使用标记-整理算法。因为老年代中的对象存活时间较长,所以会产生大量的内存碎片。标记-整理算法通过整理过程来解决这个问题。

总结

JVM垃圾回收算法包括标记-清除算法、复制算法、标记-整理算法和分代收集算法等。不同的垃圾回收算法适用于不同的场景,需要根据具体情况进行选择。对于Java程序开发人员来说,理解JVM垃圾回收算法对于优化程序性能至关重要。

  • 标题: JVM 垃圾回收算法
  • 作者: Heer Liu
  • 创建于: 2020-06-06 21:55:10
  • 链接: https://blog.heer.love/posts/94863c7b/
  • 版权声明 : 本文章采用 CC BY-NC-SA 4.0 进行许可。
推荐阅读
Java 对象的生命周期 Java 对象的生命周期 Java 对象是否存活 Java 对象是否存活 CMS 垃圾回收器 CMS 垃圾回收器