Below you will find pages that utilize the taxonomy term “Gc”
April 9, 2021
GC 对根对象扫描实现的源码分析
"\u003ch1 id=\"工作池gcwork\"\u003e工作池gcWork\u003c/h1\u003e\n\u003cp\u003e工作缓存池(\u003ccode\u003ework pool\u003c/code\u003e)实现了生产者和消费者模型,用于指向灰色对象。一个灰色对象在工作队列中被扫描标记,一个黑色对象表示已被标记不在队列中。\u003c/p\u003e\n\u003cp\u003e写屏障、根发现、栈扫描和对象扫描都会生成一个指向灰色对象的指针。扫描消费时会指向这个灰色对象,从而将先其变为黑色,再扫描它们,此时可能会产生一个新的指针指向灰色对象。这个就是三色标记法的基本知识点,应该很好理解。\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003egcWork\u003c/code\u003e 是为垃圾回收器提供的一个生产和消费工作接口。\u003c/p\u003e\n\u003cp\u003e它可以用在stack上,如\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e(preemption must be disabled)\ngcw := \u0026amp;getg().m.p.ptr().gcw\n.. call gcw.put() to produce and gcw.tryGet() to consume ..\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e在标记阶段使用gcWork可以防止垃圾收集器转换到标记终止,这一点很重要,因为gcWork可能在本地持有GC工作缓冲区。可以通过禁用抢占(\u003ccode\u003esystemstack\u003c/code\u003e 或 \u003ccode\u003eacquirem\u003c/code\u003e)来实现。\u003c/p\u003e\n\u003cp\u003e数据结构\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003etype gcWork struct {\n\twbuf1, wbuf2 …\u003c/code\u003e\u003c/pre\u003e"
April 7, 2021
Runtime: Golang GC源码分析
"\u003cp\u003e在阅读此文前,需要先了解一下三色标记法以及混合写屏障这些概念。\u003c/p\u003e\n\u003cp\u003e源文件 \u003ccode\u003e[src/runtime/mgc.go](https://github.com/golang/go/blob/go1.16/src/runtime/mgc.go)\u003c/code\u003e 版本 1.16.2。\u003c/p\u003e\n\u003ch1 id=\"基本知识\"\u003e基本知识\u003c/h1\u003e\n\u003cp\u003e在介绍GC之前,我们需要认识有些与GC相关的基本信息,如GC的状态、模式、统计信息等。\u003c/p\u003e\n\u003ch2 id=\"三种状态\"\u003e三种状态\u003c/h2\u003e\n\u003cp\u003e共有三种状态\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econst (\n\t_GCoff = iota // GC not running; sweeping in background, write barrier disabled\n\t_GCmark // GC marking roots and workbufs: allocate black, write barrier ENABLED\n\t_GCmarktermination // GC mark termination: allocate black, P\u0026#39;s help GC, write barrier ENABLED\n) …\u003c/code\u003e\u003c/pre\u003e"
April 6, 2021
Golang中的切片与GC
"\u003cp\u003e今天再看 \u003ccode\u003etimer\u003c/code\u003e 源码的时候,在函数 \u003ccode\u003e[clearDeletedTimers()](https://github.com/golang/go/blob/go1.16.2/src/runtime/time.go#L904-L992)\u003c/code\u003e 里看到一段对切片的处理代码,实现目的就是对一个切片内容进行缩容。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e// src/runtime/time.go\n\n// The caller must have locked the timers for pp.\nfunc clearDeletedTimers(pp *p) {\n\ttimers := pp.timers\n\t......\n\t// 对无用的切片元素赋值 nil\n\tfor i := to; i \u0026lt; len(timers); i++ {\n\t\ttimers[i] = nil\n\t}\n\n\tatomic.Xadd(\u0026amp;pp.deletedTimers, -cdel)\n\tatomic.Xadd(\u0026amp;pp.numTimers, -cdel)\n\tatomic.Xadd(\u0026amp;pp.adjustTimers, -cearlier) …\u003c/code\u003e\u003c/pre\u003e"
March 22, 2021
学习Golang GC 必知的几个知识点
"\u003cp\u003e对于gc的介绍主要位于 \u003ccode\u003e[src/runtime/mgc.go](https://github.com/golang/go/blob/go1.16.2/src/runtime/mgc.go)\u003c/code\u003e,以下内容是对注释的翻译。\u003c/p\u003e\n\u003ch2 id=\"gc-四个阶段\"\u003eGC 四个阶段\u003c/h2\u003e\n\u003cp\u003e通过源文件注释得知GC共分四个阶段:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eGC 清理终止 (\u003ccode\u003eGC performs sweep termination\u003c/code\u003e)\na. \u003ccode\u003eStop the world\u003c/code\u003e, 每个P 进入GC \u003ccode\u003esafepoint\u003c/code\u003e(安全点),从此刻开始,万物静止。\nb. 清理未被清理的span,如果GC被强制执行时才会出现这些未清理的span\u003c/li\u003e\n\u003cli\u003eGC 标记阶段(\u003ccode\u003eGC performs the mark phase\u003c/code\u003e)\na. 将gc标记从 \u003ccode\u003e_GCoff\u003c/code\u003e 修改为 \u003ccode\u003e_GCmark\u003c/code\u003e,开启写屏障(\u003ccode\u003ewrite barries\u003c/code\u003e)和 协助助手(\u003ccode\u003emutator assists\u003c/code\u003e),将根对象放入队列。 在STW期间,在所有P都启用写屏障之前不会有什么对象被扫描。\nb. \u003ccode\u003eStart the world\u003c/code\u003e(恢复STW)。标记工作线程和协助助手并发的执行。对于任何指针的写操作和指针值,都会被写屏障覆盖,使新分配的对象标记为黑 …\u003c/li\u003e\u003c/ol\u003e"
March 5, 2021
Golang什么时候会触发GC
"\u003cp\u003eGolang采用了三色标记法来进行垃圾回收,那么在什么场景下会触发这个GC动作呢?\u003c/p\u003e\n\u003cp\u003e源码主要位于文件 \u003ccode\u003e[src/runtime/mgc.go](https://github.com/golang/go/blob/go1.16/src/runtime/mgc.go)\u003c/code\u003e go version 1.16\u003c/p\u003e\n\u003cp\u003e触发条件从大方面来说,分为 \u003ccode\u003e手动触发\u003c/code\u003e 和 \u003ccode\u003e系统触发\u003c/code\u003e 两种方式。手动触发一般很少用,主要通过开发者调用 \u003ccode\u003eruntime.GC()\u003c/code\u003e 函数来实现,而对于系统自动触发是 \u003ccode\u003e运行时\u003c/code\u003e 根据一些条件自行维护的,这也正是本文要介绍的内容。\u003c/p\u003e\n\u003cp\u003e不管哪种触发方式,底层回收机制是一样的,所以我们先看一下手动触发,看看能否根据它来找GC触发所需的条件。\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e// src/runtime/mgc.go\n\n// GC runs a garbage collection and blocks the caller until the\n// garbage collection is complete. It may also block the entire\n// program.\nfunc GC() {\n\tn := …\u003c/code\u003e\u003c/pre\u003e"