go语言条件变量 go变量声明

Golang什么时候会触发GCGolang采用go语言条件变量了三色标记法来进行垃圾回收,那么在什么场景下会触发这个回收动作呢go语言条件变量?
源码主要位于文件src/runtime/mgc.gogo version 1.16
触发条件从大方面说,可分为 手动触发 和 系统触发 两种方式 。手动触发一般很少用,主要由开发者通过调用runtime.GC()函数来实现,而对于系统自动触发是运行时根据一些条件判断来进行的,这也正是本文要介绍的内容 。
不管哪种触发方式,底层回收机制是一样的 , 所以go语言条件变量我们先看一下手动触发,根据它来找系统触发的条件 。
可以看到开始执行GC的是gcStart()函数,它有一个gcTrigger参数,是一个触发条件结构体 , 它的结构体也很简单 。
其实在Golang 内部所有的GC都是通过gcStart()函数,然后指定一个 gcTrigger的参数来开始的 , 而手动触发指定的条件值为gcTriggerCycle。gcStart 是一个很复杂的函数,有兴趣的可以看一下源码实现 。
对于kind的值有三种,分别为 gcTriggerHeap 、gcTriggerTime和gcTriggerCycle。
运行时会通过gcTrigger.test()函数来决定是否需要触发GC,只要满足上面基中一个即可 。
到此我们基本明白了这三种触发GC的条件,那么对于系统自动触发这种 , Golang 从一个程序的开始到运行,它又是如何一步一步监控到这个条件的呢?
其实 runtime 在程序启动时,会在一个初始化函数init()里启用一个forcegchelper()函数,这个函数位于proc.go文件 。
为了减少系统资源占用,在forcegchelper函数里会通过goparkunlock()函数主动让自己陷入休眠,以后由sysmon()监控线程根据条件来恢复这个gc goroutine 。
可以看到sysmon()会在一个for语句里一直判断这个 gcTriggerTime这个条件是否满足,如果满足的话 , 会将forcegc.g这个 goroutine 添加到全局队列里进行调度(这里forcegc是一个全局变量) 。
调度器在调度循环runtime.schedule中还可以通过垃圾收集控制器的runtime.gcControllerState.findRunnabledGCWorker获取并执行用于后台标记的任务 。
Golang入门到项目实战 | golang并发变成之通道channel Go提供了一种称为通道的机制,用于在goroutine之间共享数据 。当您作为goroutine执行并发活动时,需要在goroutine之间共享资源或数据,通道充当goroutine之间的管道(管道)并提供一种机制来保证同步交换 。
根据数据交换的行为 , 有两种类型的通道:无缓冲通道和缓冲通道 。无缓冲通道用于执行goroutine之间的同步通信,而缓冲通道用于执行异步通信 。无缓冲通道保证在发送和接收发生的瞬间两个goroutine之间的交换 。缓冲通道没有这样的保证 。
通道由make函数创建,该函数指定chan关键字和通道的元素类型 。
这是创建无缓冲和缓冲通道的代码块:
语法
使用内置函数make创建无缓冲和缓冲通道 。make的第一个参数需要关键字chan,然后是通道允许交换的数据类型 。
这是将值发送到通道的代码块需要使用-运算符:
语法
一个包含5个值的缓冲区的字符串类型的goroutine1通道 。然后我们通过通道发送字符串“Australia” 。
这是从通道接收值的代码块:
语法
- 运算符附加到通道变量(goroutine1)的左侧,以接收来自通道的值 。
在无缓冲通道中,在接收到任何值之前没有能力保存它 。在这种类型的通道中,发送和接收goroutine在任何发送或接收操作完成之前的同一时刻都准备就绪 。如果两个goroutine没有在同一时刻准备好,则通道会让执行其各自发送或接收操作的goroutine首先等待 。同步是通道上发送和接收之间交互的基础 。没有另一个就不可能发生 。

推荐阅读