Go语言内存管理与内存清理

Go:内存管理与内存清理

清理内存是一个过程,它能够让 Go 知道哪些内存段最近可用于分配。但是,它并不会使用将位置 0 的方式来清理内存。

将内存置0

将内存置 0 的过程 —— 就是把内存段中的所有位赋值为 0 —— 是在分配过程中即时执行的。

然后,第一个分配就开始了:

分配过程将会再一次出现,之后, GC 将会启动去释放不再被使用的内存。在标记期间,GC 会用一个位图gcmarkBits 来跟踪在使用中的内存。让我们通过我们运行的程序以相同的示例为例,在第一个块不再被使用的地方。

有关更多关于标记和着色阶段的信息,我建议你阅读我的这篇文章 Go:GC 是如何标记内存的?

现在,我们可以使用 gomarkBits精确查看可用于分配的内存。Go 现在也使用gomarkBits 代替了allocBits ,这个操作就是内存清理:

清理阶段

Go 提供了两种方式来清理内存:

  • 使用一个工作程序在后台等待,一个一个的清理这些范围。
  • 当分配需要一个范围的时候即时执行。

关于后台工作程序,当开始运行程序时,Go 将设置一个后台运行的 Worker(唯一的任务就是去清理内存),它将进入睡眠状态并等待内存段扫描:

与 GC 周期的冲突

正如之前看到的,由于后台只有一个 worker 在清理内存块,清理过程可能会花费一些时间。但是,我们可能想知道如果另一个 GC 周期在一次清理过程中启动会发生什么。在这种情况下,这个运行 GC 的 goroutine 就会在开始标记阶段前去协助完成剩余的清理工作。让我们举个例子看一下连续调用两次 GC,包含数千个对象的内存分配的过程。


via:来源链接

作者:Vincent Blanchon 译者:sh1luo 校对:[](https://github.com/

本文由 GCTT 原创编译,Go中文网 荣誉推出