【GC的过程】

简介: 【GC的过程】

GC(垃圾回收)是程序自动管理内存的一种机制,通过扫描内存中的对象和引用,自动确定哪些对象是已死的(即无法再被访问),并将这些对象标记为垃圾,释放它们所占用的内存空间。下面我们将介绍GC的过程,并附上Java代码示例来说明。


1. 标记阶段

在标记阶段,GC扫描所有的对象,找出所有可达对象,这些对象是指在应用程序中仍然被引用的对象,将这些对象标记为存活对象。未被标记的对象就会被判定为垃圾。为了实现标记过程,GC需要对整个堆进行扫描,记录哪些对象是存活对象。

Java代码示例:

public class GCExample {
   public static void main(String[] args) {
      // 创建对象
      Object obj1 = new Object();
      Object obj2 = new Object();
      Object obj3 = new Object();
      // 将obj1和obj2设为相互引用
      obj1.setReference(obj2);
      obj2.setReference(obj1);
      // 将obj3设为root对象
      root = obj3;
      // 执行标记过程
      mark(root);
   }
   // 在标记过程中,使用递归算法遍历所有存活对象
   public static void mark(Object obj) {
      if (obj.isMarked()) {
         return;
      }
      obj.mark();
      Object[] references = obj.getReferences();
      for (Object ref : references) {
         mark(ref);
      }
   }
}

在上面的代码示例中,我们创建了三个对象obj1、obj2和obj3,并将obj1和obj2相互引用,将obj3设置为root对象。在执行mark方法时,从根对象obj3开始,使用递归算法遍历所有存活对象,将遍历到的对象标记为存活对象。

2. 清除阶段

在清除阶段,GC清除被标记为垃圾的对象,收回它们所占用的内存空间。清除过程是在后台进行的,应用程序不会受到影响。在清除过程中,GC会将被标记为垃圾的对象从堆中清除。这些对象的内存空间将被释放,以便可供后续程序使用。

Java代码示例:

public static void sweep() {
   for (Object obj : heap) {
      if (!obj.isMarked()) {
         heap.remove(obj);
      } else {
         obj.unmark();
      }
   }
}

在上面的代码示例中,我们遍历整个堆,对于所有没有被标记的对象,将其从堆中清除。而对于被标记了的对象,将其标记状态重置为未标记。

3. 压缩阶段

在压缩阶段,GC会将存活对象向堆的一端移动,以便获得一块连续的内存空间。这个过程也称为内存整理。这个过程的目的是使内存空间更加紧凑,并且减少内存碎片的数量,从而提高内存利用率。

Java代码示例:

public static void compact() {
   int offset = 0;
   for (Object obj : heap) {
      if (obj.isMarked()) {
         obj.move(offset);
         offset += obj.getSize();
      }
   }
}

在上面的代码示例中,我们遍历所有存活对象,将它们向堆的一端移动,并更新它们在堆中的位置。在移动对象时,我们需要记录它们的偏移量,以便正确地更新它们的引用。

以上就是GC的三个阶段:标记阶段、清除阶段和压缩阶段。这些阶段的实现方式因开发语言而异,但是它们的基本原理是相同的。

小故事

有一位名叫小明的程序员,在工作中经常使用Java语言编写代码。他知道Java的优点之一是可以自动进行垃圾回收,也就是GC。但是他对GC的具体过程还不是很了解。有一天,他向同事请教,同事给他讲了一个小故事来说明GC的过程:

故事是这样的:有一位园丁在花园里种了一些花,他会定期巡视花园,将枯萎的花朵摘掉。这样,花园里的花就能保持鲜艳美丽。这位园丁就像是JVM的垃圾回收器,花就像是程序中的不再使用的对象。

在Java程序中,当一个对象不再被引用时,垃圾回收器就会将其标记为垃圾对象,并将其从内存中清除。这个过程分为两部分:标记和清除。

标记阶段:垃圾回收器会遍历堆中的所有对象,并标记哪些对象是可达的(被引用的)和哪些对象是不可达的(未被引用的)。

清除阶段:垃圾回收器会清除所有的不可达对象,并释放它们占用的内存空间。

就像园丁巡视花园一样,垃圾回收器需要周期性地运行,以便及时地清理垃圾对象,释放内存。如果垃圾回收器不能及时地清除垃圾对象,程序可能会因为内存泄漏而出现问题,甚至导致程序崩溃。

通过这个小故事,小明理解了JVM GC的过程,他感到更加安心地使用Java语言编写代码。


相关文章
|
机器人 Python
Robot Framework之python脚本调用
前言 喜欢使用RF的原因之一就是能自己定义关键字,这篇就简单说下如何创建系统关键字,先来个最简单的,求比较两个数的大小 一、建立库文件 假设python的安装路径在D:/下面(作者是放在D:\python\python27) 1、在D:\python\...
4176 0
|
6月前
|
关系型数据库 MySQL Java
SpringBoot集成Sharding-Jdbc分库分表
ShardingSphere是一套开源分布式数据库中间件解决方案,包含Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar三款产品,提供数据分片、分布式事务和数据库治理功能,适用于多样化应用场景。
875 0
SpringBoot集成Sharding-Jdbc分库分表
|
6月前
|
算法 安全 新能源
基于DistFlow的含分布式电源配电网优化模型【IEEE39节点】(Python代码实现)
基于DistFlow的含分布式电源配电网优化模型【IEEE39节点】(Python代码实现)
447 0
|
Java
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
Jinfo 查看 jvm 配置及使用 Jstat 查看堆内存使用与垃圾回收
527 5
|
存储 安全 Java
深入理解ThreadLocal:线程局部变量的机制与应用
在多线程编程中,`ThreadLocal`变量提供了一种线程安全的解决方案,允许每个线程拥有自己的变量副本,从而避免了线程间的数据竞争。本文将详细介绍`ThreadLocal`的工作原理、使用方法以及在实际开发中的应用场景。
359 3
|
开发框架 监控 数据可视化
90%的项目经理都在使用的15款项目管理工具清单
【11月更文挑战第4天】以下是15款广受项目经理欢迎的项目管理工具:Jira、Worktile、Pingcode、Asana、Trello、Basecamp、Monday.com、Smartsheet、ProofHub、VersionOne、Pivotal Tracker、ClickUp、ProjectLibre、OpenProject 和 禅道。这些工具各具特色,适用于不同规模和类型的项目管理需求。
356 3
|
开发框架 Java 开发者
Spring Boot中的自动装配原理
Spring Boot中的自动装配原理
3547 1
|
Ubuntu Linux Apache
在Linux中,如何使用logrotate命令管理日志文件?
在Linux中,如何使用logrotate命令管理日志文件?
|
人工智能 自然语言处理 监控
RPA学习第一课 --初识RPA
RPA学习第一课 --初识RPA
10451 3
|
存储 Java API
Spring Boot中的数据脱敏处理
Spring Boot中的数据脱敏处理