JVM中如何实现垃圾收集

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

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

对象创建:

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

引用追踪:

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

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

标记阶段:

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

  • 标记-清除算法:

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

  • 标记-复制 算法:

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

  • 标记-整理算法:

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

清理阶段:

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

内存整理:

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

相关推荐
用户094248568034 小时前
第18章:ConcurrentHashMap与并发容器实战
java·jvm
一条破秋裤8 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm
bksczm11 小时前
零基础面试题1
jvm·数据结构·算法
今天的砖头有点烫手啊12 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java·jvm
johnny23313 小时前
JVM生态下Web开发框架:SparkJava、Javalin、Micronaut、SparkKotlin
jvm
晨小安1 天前
ThreadLocal及其内存泄漏问题深度解析
java·jvm·tomcat·哈希表
jingli91 天前
一个测试用例把连接池卡死 30 秒:SQLite 连接池 max_size=1 下的重入自锁复盘
jvm·sqlite·测试用例
imDwAaY2 天前
Java中垃圾回收器 G1 和 CMS 有什么区别?
jvm·后端
xiaoqiMikko2 天前
JVM 线上排查实战(五):升 JDK 17 后进程起不来,十几个老 GC 参数挨个实测(完结)
java·jvm
Flynt2 天前
Java 27 悄悄改了 3 个默认值,我在 1 核小机器上逐个验证了一遍
java·jvm·性能优化