上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
3.2.1 阈值属性
与 GC 相关的内存数据由 memstats 记录,其中与垃圾回收有关的重点字段如下:
- next_gc : 预期下次回收启动时,已分配堆大小。
- gc_trigger : 实际触发阈值,通常要小于预期值。
- triggerRatio : 由控制器根据回收周期内统计数据计算得出,用于调整阈值比率。
- heap_marked : 标记结束后,存活对象大小总和。
- gcpercent : 环境变量 GOGC 值(默认 100),调整最小堆和比率上限。
triggerRatio、heap_marked 默认值在 gcinit 里设定。
triggerRatio
在相关函数(setGCPercent、gcSetTriggerRatio)里能找到计算公式。
heapminimum = defaultHeapMinimum * gcpercent / 100 maxTriggerRatio = 0.95 * gcpercent / 100 gc_trigger = heap_marked * (1 + triggerRatio) // 0.6 <= triggerRatio <= 0.95 next_gc = heap_marked + heap_marked * gcpercent/100
trigger 和 goal 默认值 ^0 是个无法达到的值(18446744073709551615)。
如果 GOGC < 0,那么阈值无法触发,从而变相阻止垃圾回收启动。
标记结束(gcMarkDone)时,调用 gcControllerState.endCycle 计算阈值比率。
// mgc.go func gcSetTriggerRatio(triggerRatio float64) { // 预期目标值。 goal := ^uint64(0) if gcpercent >= 0 { goal = memstats.heap_marked + memstats.heap_marked*uint64(gcpercent)/100 } // 设置回收比率(0.6 <= ? <= 0.95)。 const minTriggerRatio = 0.6 if triggerRatio < minTriggerRatio { triggerRatio = minTriggerRatio } else if gcpercent >= 0 { maxTriggerRatio := 0.95 * float64(gcpercent) / 100 if triggerRatio > maxTriggerRatio { triggerRatio = maxTriggerRatio } } memstats.triggerRatio = triggerRatio // 通过比率计算绝对触发阈值。 trigger := ^uint64(0) if gcpercent >= 0 { trigger = uint64(float64(memstats.heap_marked) * (1 + triggerRatio)) // 最小、最大范围。 minTrigger := heapminimum if trigger < minTrigger { trigger = minTrigger } if trigger > goal { goal = trigger } } memstats.gc_trigger = trigger memstats.next_gc = goal }
gcpercent
环境变量 GOGC 是除强制回收函数外,对垃圾回收的唯一干预手段。
GOGC 百分比数值参与阈值比率计算,进而影响回收触发时机。
1. < 0 :(off),关闭垃圾回收。
2. > 0 : 增大垃圾回收阈值,延迟回收。
3. 默认 100,表示阈值接近当前标记结果的两倍。
调用 runtime.GC 强制执行垃圾回收,不受 GOGC 和阈值限制。
但该函数会阻塞用户逻辑执行,直至回收完全结束。
// mgc.go func readgogc() int32 { p := gogetenv("GOGC") if p == "off" { return -1 } if n, ok := atoi32(p); ok { return n } return 100 }
func setGCPercent(in int32) (out int32) { // 当前值,用于返回。 out = gcpercent if in < 0 { in = -1 } gcpercent = in heapminimum = defaultHeapMinimum * uint64(gcpercent) / 100 // 设置阈值和比率。 gcSetTriggerRatio(memstats.triggerRatio) return out }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论