golang GC机制

本文介绍了Golang的垃圾回收(GC)机制,包括触发条件、优化方法,如调整GOGC参数、减少对象分配、处理string与[]byte转换,以及避免使用+连接string。还详细阐述了GC的处理过程,如三色标记法、写屏障、STW阶段以及内存分配机制,特别是对象分配流程。最后提到了new和make在内存分配上的区别。
摘要由CSDN通过智能技术生成

Golang自1.5版本开始引入三色GC,多次改进,GC停顿时间降低到1ms。

一:GC的触发

GC的触发条件有以下几种:

  • gcTriggerAlways:强制触发GC
  • gcTriggerHeap:当前分配的内存达到一定值就触发GC
  • gcTriggerTime:当一定时间没有执行过GC触发
  • gcTriggerCycle:要求启动新一轮的GC,已启动则跳过,手动触发GC的runtime.GC()会使用这个条件
    其中gcTriggerHeap和gcTriggerTime这两个条件是自然触发的。
    gcTriggerHeap的判断依据为:
memstats.heap_live >= memstats.gc_trigger //heap_live is the number of bytes considered live by the GC
其中memstats.gc_trigger的计算公式是:
trigger = unit64(float64(memstats.heap_marked)*(1+triggerRatio))//heap_marked is the number of bytes marked by the previous GC
tiggerRatio 与goalGrowthRatio正相关
goalGrowthRatio = float64(gcpercent)/100

公式中的goalGrowthRatio“目标Heap增长率”通过设置环境变量GOGC(gcpercent)调整,默认值为100。
gcTriggerTime的判断依据为:

t.now - lastgc > forcegcperiod

其中forcegcperiod的定义是2分钟,也就是2分钟没有执行GC就会强制触发。

二:如何进行GC优化

2.1:硬性参数GOGC
比如当前程序使用4M堆内存,即memstats.heap_marked内存为4M,当程序占用的内存上升到memstats.heap_marked*(1+GOGC/100)=8M时候,gc就会被触发,开始进行相关的gc操作。
如何对GOGC的参数进行设置,要根据生产情况中的实际场景来定。增加它的值可以减少GC触发但需保证内存足够大。如果你的内存少,只能更频繁的GC以节省内存,那么降低GOGC值。设置GOGC=off可以彻底关掉GC
2.2:减少对象分配
内存复用,减少对象申请。下面的样例代码中实现内存复用,其关键是一个缓存的管道buffer,可存储5个字节数组,当程序需要一个字节数组时候,优先使用select从缓存的管道中去取。最终内存池中的内存和从操作系统请求的内存很接近,堆中只有很少量的未使用内存最终返还给操作系统。

package main
import (
    "fmt"
    "math/rand"
    "runtime"
    "time"
)
func makeBuffer() []byte {
   
    return make([]byte, rand.Intn(5000000)+5000000)
}
func main() {
   
    pool := make([][]byte, 20)
    buffer := make(chan []byte, 5)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值