JVM的垃圾回收机制和Golang的垃圾回收机制

本文探讨了JVM和Golang的垃圾回收机制,包括可达性分析算法、引用计数算法、标记-清除、复制、分代收集等JVM算法,以及Golang的mark and sweep算法。分析了两种语言在垃圾回收中的相似点和不同点,以及各自的发展趋势。

JVM的垃圾回收机制和Golang的垃圾回收机制


前言

为什么要写这篇文章,在仔细的了解了jvm垃圾回收机制和Golang的回收机制之后发现其有很多的相同点和不同点,未来的发展会不会有共通之处,这是我的想法。


一、 哪些内存需要回收

在弄清答案之前我们首先要知道什么样数据我们是可以回收的。

JVM的内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。
其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生、随线程而灭,因此这几个区域的内存分配和回收都具备确定性,就不需要过多考虑回收的问题
Java堆区和方法区则不一样,内存的分配和回收是动态的所以针对这部分区域有一些特定的算法。

二、算法

2.1可达性分析算法

在这里插入图片描述
简单的说法就是看其是否于GCRoot相连,如果不相连我们认为其可回收。
在Java语言中,可作为GC Roots的对象包括下面几种:
1、虚拟机栈中引用的对象(栈帧中的本地变量表);
2、方法区中类静态属性引用的对象;
3、 方法区中常量引用的对象;
4、本地方法栈中JNI(Native方法)引用的对象。
(1)我们可以思考一个问题,那就是会不会出现循环引用的问题?
不会,我们看可达性分析算法的结构,其值是向下进行搜索的不会得到闭环。
(2)不被对象图内对象引用的会不会被直接回收?
不会的,在这个算法中有一个标记的过程,只有当对象被标记了两次才会被回收。筛选的条件是此对象是否有必要执行finapze()方法。

GC垃圾回收机制旨在自动管理内存,回收不再使用的对象所占用的内存空间,以提高内存利用率,避免内存泄漏。以下从原理、JVM相关、不同语言的算法等方面进行介绍: ### GC原理 进行垃圾回收的目的在于回收不再使用的内存,避免内存泄漏,提高系统的稳定性性能。在Java中,判断一个对象是否为垃圾通常借助可达性分析算法,其中涉及到GC Roots的概念。GC Roots是一组对象,从这些对象开始进行可达性分析,若一个对象与GC Roots没有引用链相连,则该对象被判定为垃圾对象。可作为GC Roots的对象包括虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI(即一般说的Native方法)引用的对象等 [^1]。 ### JVM回收算法 #### 内存分配 JVM的内存主要分为新生代、老年代永久代(Java 8及以后称为元空间)。新生代用于存放新创建的对象,老年代存放生命周期较长的对象,永久代(元空间)主要存放类的元数据等信息 [^1]。 #### 回收算法 - **标记 - 清除(Mark - sweep)**:先标记出所有需要回收的对象,然后统一回收被标记的对象。该算法的缺点是会产生大量内存碎片,可能导致后续无法为大对象分配连续的内存空间。 - **复制(Copying)**:将内存分为大小相等的两块,每次只使用其中一块。当这一块内存用完后,将还存活的对象复制到另一块上,然后把已使用的内存空间一次清理掉。这种算法不会产生内存碎片,但会浪费一半的内存空间。 - **标记 - 整理(Mark - Compact)**:先标记出所有需要回收的对象,然后让所有存活的对象都向一端移动,最后直接清理掉端边界以外的内存。该算法避免了内存碎片的问题,但移动对象的成本较高。 - **分代收集算法**:根据对象的存活周期将内存划分为不同的区域,如新生代、老年代永久代(元空间)。新生代采用复制算法,老年代采用标记 - 清除或标记 - 整理算法 [^1]。 ### 不同语言的GC机制 #### Java Java的GC过程中存在“STW”(stop the world)问题,即触发垃圾回收时,当前程序的其他业务逻辑可能会被暂停。不过,随着Java的发展,如今已能将“STW”控制在1ms以内 [^2]。 #### Golang Golang中的垃圾回收主要应用三色标记法,GC过程其他用户goroutine可并发运行,但需要一定时间的STW(stop the world)。在STW过程中,CPU不执行用户代码,全部用于垃圾回收,影响较大。Golang进行了多次迭代优化来解决这个问题。在Go V1.3之前采用标记 - 清除(mark and sweep)算法。三色标记法的步骤如下: 1. 初始化图例。 2. GC开始,遍历root,将直接可达的标记为灰色。 3. 遍历灰色列表,将直接可达的标记为灰色,自身标记为黑色。 4. 重复上述步骤,直到标记完所有对象。 5. 将标记为白色的对象进行垃圾回收(GC完成) [^3][^4]。 ### 示例代码 以下是一个简单的Java示例,展示对象被垃圾回收的情况: ```java public class GCDemo { public static void main(String[] args) { // 创建一个对象 Object obj = new Object(); // 将对象引用置为null,使其成为垃圾对象 obj = null; // 建议JVM进行垃圾回收 System.gc(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值