JVM中如何实现垃圾收集

Java虚拟机(JVM)使用垃圾收集器(Garbage Collector)来管理内存,清理不再使用的对象以释放内存空间。垃圾收集的主要目标是自动化内存管理,使开发人员无需显式地释放不再使用的内存,从而降低了内存泄漏的风险。

JVM中垃圾收集的一般过程:

对象创建:

当应用程序创建新对象时,内存分配器负责为应用程序中使用的新对象分配内存空间。当应用程序需要创建一个新对象时,它会向内存分配器发出请求,请求分配一定大小的内存空间。内存分配器会检查可用的内存空间,并为该请求分配合适的大小的空间。通常,内存分配器会分配连续的内存空间,并返回该空间的起始地址。

引用追踪:

垃圾收集器通过引用追踪算法来识别和收集不再使用的内存对象,以便回收内存空间。引用追踪算法基于一个简单的假设:当一个对象可以被访问时,它就不是垃圾。因此,垃圾收集器需要追踪哪些对象是可以被访问的,以及哪些对象是不可访问的。

垃圾收集器通过根集来开始引用追踪。根集包括全局变量、静态变量和调用栈中的指针等,它们是程序中始终可访问的对象。垃圾收集器从根集开始,递归地遍历所有可访问对象,标记为可访问的对象,并将不可访问的对象标记为垃圾。

标记阶段:

在引用追踪过程中,垃圾收集器标记所有可达的对象。一般有三种主要的标记算法:标记-清除、标记-复制和标记-整理算法。

  • 标记-清除算法:

    如它的名字一样,算法分为"标记"和"清除"两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。这种算法可能会导致内存碎片化,影响性能。

  • 标记-复制 算法:

    为了解决标记-清除算法面对大量可回收对象时执行效率低的问题,1969年Fenichel提出了一种称为"半区复制"(Semispace Copying)的垃圾收集法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这种方式减少了内存碎片,但是需要额外的空间。

  • 标记-整理算法:

    标记-整理算法的标记过程仍然与"标记-清除"算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。这也有助于减少内存碎片。

清理阶段:

垃圾收集器在标记阶段之后,对被标记为垃圾的对象进行回收和内存释放的过程。

内存整理:

在清理阶段之后,对于某些垃圾收集算法,可能需要进行内存整理,以便将存活对象集中在一起,减少碎片化。这一步通常涉及移动对象的位置。

相关推荐
打工仔折腾 AI10 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
用户0942485680315 小时前
第22章:JIT编译分层——Interpreter、C1、C2与热点探测
java·jvm
乌暮16 小时前
JVM 原理与实践:从运行时数据区到线上故障排查
java·开发语言·jvm·后端·学习·面试
长河1 天前
Java的GC(垃圾回收)中,标记无用对象的核心方法是可达性分析算法
java·jvm·算法
可乐ea2 天前
GitHub Security Lab 开源 Fuzzing Taskflow:让 LLM 智能体自己跑完 C/C++ 模糊测试
jvm·c++·github·模糊测试·mcp·代码agent·智能体自动化
一条破秋裤2 天前
Linux 线程同步:读写锁
java·linux·jvm
wuminyu2 天前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++
一条破秋裤2 天前
Linux 线程同步:条件变量
java·linux·jvm
谢亮_vipxieliang2 天前
GC 入门:G1 与 ZGC 怎么选
java·jvm·算法
小溪学编程3 天前
从 C++ 的规范变迁看语言发展
jvm·c++·面试