Go自动内存管理和优化(五)—— Go垃圾回收机制

一、本次学习重点内容:

1、Go的自动内存管理

2、Go的分代GC

二、详细知识点介绍:

1、自动内存管理——简介

动态内存:

程序在运行时根据需求动态分配的内存: malloc( )

自动内存管理(垃圾回收):

由程序语言的运行时系统管理动态内存

目的:

1、避免手动内存管理,专注于实现业务逻辑

2、保证内存使用的正确性和安全性: double-freeproblem, use-after-free problem

三个任务:

1、为新对象分配空间

2、找到存活对象

3、回收死亡对象的内存空间

2、自动内存管理——相关概念:

GC算法:

Mutator:业务线程,分配新对象,修改对象指向关系

Collector: GC线程,找到存活对象,回收死亡对象的内存空间

Serial GC:只有一个collector

Parallel GC:支持多个collectors同时回收的GC算法

Concurrent GC: mutator(s)和collector(s)可以同时执行,Collectors必须感知对象指向关系的改变!

image-20230206203835317

GC算法评价:

安全性(Safety):不能回收存活的对象 基本要求

吞吐率(Throughput)花在GC上的时间

image-20230206204629267

暂停时间(Pause time):stop the world (STW) 业务是否感知

内存开销(Space overhead) GC元数据开销

跟踪垃圾回收:

对象被回收的条件:指针指向关系不可达的对象

标记根对象:

根对象:静态变量、全局变量、常量、线程栈等

标记:找到可达对象

求指针指向关系的传递闭包:从根对象出发,找到所有可达对象

image-20230206205308227

清理:所有不可达对象

步骤:

1、将存活对象复制到另外的内存空间(Copying GC)

2、将死亡对象的内存标记为“可分配”(Mark-sweep GC)

3、移动并整理存活对象(Mark-compact GC)

copying GC:image-20230206205621808

Mark-sweep GC: 使用free list 管理空闲内存

image-20230206205738762

Mark-compact GC: 原地整理

image-20230206205849165

3、分代GC

分代假说(Generational hypothesis): most objects die young

现状:很多对象在分配出来后很快就不再使用了

每个对象都有年龄:经历过GC的次数

目的:

对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销

不同年龄的对象处于heap 的不同区域:

image-20230206210334535

年轻代(Young generation):

常规的对象分配

由于存活对象很少,可以采用copying collection

GC吞吐率很高

老年代(Old generation):

对象趋向于一直活着,反复复制开销较大

可以采用mark-sweep collection

引用计数:

每个对象都有一个与之关联的引用数目。

对象存活的条件:当且仅当引用数大于0

image-20230206210816083

优点:

1、内存管理的操作被平摊到程序执行过程中。

2、内存管理不需要了解runtime 的实现细节:C++智能指针(smart pointer)。

缺点:

1、维护引用计数的开销较大:通过原子操作保证对引用计数操作的原子性和可见性

2、无法回收环形数据结构——weak reference

3、内存开销:每个对象都引入的额外内存空间存储引用数目。

4、回收内存时依然可能引发暂停。

image-20230206211343212

三、个人总结:

​ 这次学习了自动内存管理的背景和意义,了解GO内存管理相关概念和评价方法。从垃圾回收追踪深入浅出讲解了Go垃圾回收的经典算法:复制算法,标记清除算法,标记清除压缩算法。说到了三类算法的优缺点,再到Go本身是如何合理使用三种GC算法的结合来大大降低GC的资源消耗。

猜你喜欢

转载自blog.csdn.net/qq_54353206/article/details/128908583