谈论Go什么时候会触发GC问题

文章编号:5150 安全相关 2023-10-18

在早期经常遭到唾弃的就是在垃圾回收(下称:GC)机制中STW(Stop-The-World)的时间过长。那么这个时候,我们又会好奇一点,作为STW的起始,Go语言中什么时候才会触发GC呢?

在计算机科学中,垃圾回收(GC)是一种自动管理内存的机制,垃圾回收器会去尝试回收程序不再使用的对象及其占用的内存。

最早JohnMcCarthy在1959年左右发明了垃圾回收,以简化Lisp中的手动内存管理的机制(来自@wikipedia)。

手动管理内存挺麻烦,管错或者管漏内存也很糟糕,将会直接导致程序不稳定(持续泄露)甚至直接崩溃。

GC触发的场景主要分为两大类,分别是: 谈论Go什么时候会触发GC问题

在系统触发的场景中,Go源码的src/runtime/mgc.go文件,明确标识了GC系统触发的三种场景,分别如下:

const(gcTriggerHeapgcTriggerKind=iotagcTriggerTimegcTriggerCycle)

    在手动触发的runtime.GC方法中涉及。

    在手动触发的场景下,Go语言中仅有runtime.GC方法可以触发,也就没什么额外的分类的。

    但我们要思考的是,一般我们在什么业务场景中,要涉及到手动干涉GC,强制触发他呢?

    需要手动强制触发的场景极其少见,可能会是在某些业务方法执行完后,因其占用了过多的内存,需要人为释放。又或是debug程序所需。

    在了解到Go语言会触发GC的场景后,我们进一步看看触发GC的流程代码是怎么样的,我们可以借助手动触发的runtime.GC方法来作为突破口。

    开始新的一轮GC周期,调用gcStart方法触发GC行为,开始扫描标记阶段。

    需要调用gcWaitOnMark方法等待,直到当前GC周期的扫描、标记、标记终止完成。

    需要调用sweepone方法,扫描未扫除的堆跨度,并持续扫除,保证清理完成。在等待扫除完毕前的阻塞时间,会调用Gosched让出。

    在本轮GC已经基本完成后,会调用mProf_PostSweep方法。以此记录最后一次标记终止时的堆配置文件快照。

    看完GC的基本流程后,我们有了一个基本的了解。但可能又有小伙伴有疑惑了?

    实质上在Go运行时(runtime)初始化时,会启动一个goroutine,用于处理GC机制的相关事项。

    funcinit(){goforcegchelper()}funcforcegchelper(){forcegc.g=getg()lockInit(&forcegc.lock,lockRankForcegc)for{lock(&forcegc.lock)ifforcegc.idle!=0{throw("forcegc:phaseerror")}atomic.Store(&forcegc.idle,1)goparkunlock(&forcegc.lock,waitReasonForceGCIdle,traceEvGoBlock,1)//thisgoroutineisexplicitlyresumedbysysmonifdebug.gctrace>0{println("GCforced")}gcStart(gcTrigger{kind:gcTriggerTime,now:nanotime()})}}

    在这段程序中,需要特别关注的是在forcegchelper方法中,会调用goparkunlock方法让该goroutine陷入休眠等待状态,以减少不必要的资源开销。

    在休眠后,会由sysmon这一个系统监控线程来进行监控、唤醒等行为:

    funcsysmon(){...for{...//checkifweneedtoforceaGCift:=(gcTrigger{kind:gcTriggerTime,now:now});t.test()&&atomic.Load(&forcegc.idle)!=0{lock(&forcegc.lock)forcegc.idle=0varlistgListlist.push(forcegc.g)injectglist(&list)unlock(&forcegc.lock)}ifdebug.schedtrace>0&&lasttraceint64(debug.schedtrace)*1000000<=now{lasttrace=nowschedtrace(debug.scheddetail>0)}unlock(&sched.sysmonlock)}}

    这段代码核心的行为就是不断地在for循环中,对gcTriggerTime和now变量进行比较,判断是否达到一定的时间(默认为2分钟)。

    若达到意味着满足条件,会将forcegc.g放到全局队列中接受新的一轮调度,再进行对上面forcegchelper的唤醒。

    在了解定时触发的机制后,另外一个场景就是分配的堆空间的时候,那么我们要看的地方就非常明确了。

    那就是运行时申请堆内存的mallocgc方法。核心代码如下:

    funcmallocgc(sizeuintptr,typ*_type,needzerobool)unsafe.Pointer{shouldhelpgc:=false...ifsize<=maxSmallSize{ifnoscan&&size

    小对象:如果申请小对象时,发现当前内存空间不存在空闲跨度时,将会需要调用nextFree方法获取新的可用的对象,可能会触发GC行为。

    大对象:如果申请大于32k以上的大对象时,可能会触发GC行为。

    总结在这篇文章中,我们介绍了Go语言触发GC的两大类场景,并分别基于大类中的细分场景进行了一一说明。

    到此这篇关于谈论Go什么时候会触发GC问题的文章就介绍到这了,更多相关什么时候会触发GC?内容请搜索完美下载以前的文章或继续浏览下面的相关文章希望大家以后多多支持完美下载!

    全局中部横幅
    问卷网

    免费问卷调查平台-问卷网,拥有创新的编辑界面和结果分析界面,海量的问卷和表单模板,提供20余万精品模板;支持微信,微博,QQ等多种发布模式。专注于为企业和个人提供问卷表单的创建,发布,管理,收集及分析服务。

    renrendoc.com人人文库

    人人文库(renrendoc.com)美如初恋,人人文库是一个在线文档分享平台。你可以上传设计图纸,研究报告,设计标准,策划管理方案,论文等电子文档,分享最新的行业资讯。

    蜂目云管理平台系统

    蜂目云管理平台系统专注安防云,安防监控,监控直播,人脸识别,AI分析盒,边缘计算盒子,监控摄像头,ai安全预警系统软件研发,支持主流厂商大规模,分布式,高并发视频接入,实现摄像头监控升级,监控直播,人脸识别系统,AI识别算法,iot视频监控系统,安防云存储,告警推送,智能分析,边缘计算,IoT等开放服务。

    游戏媒体

    游戏大麦是北京彼雪戈文化传播有限责任公司旗下链接国内外游戏厂商、游戏媒体、游戏玩家以及游戏第三方从业者例如游戏展览、游戏广告、showgirl、游戏KOL、游戏KOC、二次元达人的线上平台;欢迎游戏厂商分享游戏运营经验及心得,让每个玩家为自己喜爱的游戏代言。

    道一设计/宣传册设计/平面设计公司/苏州道一品牌策划有限公司

    苏州平面设计,苏州品牌设计,苏州画册设计,苏州网站设计,苏州广告设计,吴江画册设计印刷、吴中画册设计印刷、园区画册设计印刷、盛泽画册设计印刷、logo设计、VI设计、品牌全案设计

    德国红外测温仪,德国欧普士,德国optris

    北京欧万电子科技有限公司在北京,上海,山东,浙江,江苏,辽宁,河北,陕西等地供应(销售)上等的德国红外测温仪,德国欧普士,德国optris,高速红外测温仪,双色红外热像仪,在线红外热像仪,高温红外热像仪,更提供产品多元方案,如德国红外测温仪厂家,德国欧普士价格,德国optris电话,高速红外测温仪授权代理,双色红外热像仪授权代理专业团队,在线红外热像仪专业团队,高温红外热像仪大量现货,德国红外测温仪图片,德国欧普士型号等!

    钻铣床

    浙江西菱股份有限公司(www.zjxltz.com)是专注于钻铣床,攻丝机,悬臂攻丝机,齿轮式牙距攻丝机,摇臂攻丝机的数控攻丝机厂家,西菱有多品种、多规格、系列化覆盖同行业同类产品,欢迎来电洽谈

    在线名字打分

    八字网免费提供名字打分与八字精批算命,让你了解名字与生辰八字的契合度,助力好运相随,抢占人生先机。

    暖气片商城

    圣劳伦斯暖气片商城直营圣劳伦斯旗下所有产品,囊括圣劳伦斯钢制暖气片、铜铝复合暖气片、卫浴暖气片、家用暖气片、电暖气片、地暖、管材管件等暖气片产品,圣劳伦斯是暖气片十大品牌厂家之一。

    上海吉釉科技资讯科技资讯

    上海吉釉 科技资讯科技资讯为你分享科技,电脑,汽车,智能,数码,互联网,it业界,行业资讯等全方位的资讯信息

    青岛尚禹环保设备有限公司

    青岛尚禹环保设备科技有限公司自2021年4月注册成立,注册资本金500万元,2021年8月正式运行。公司专注产学研一体化,承载技术引进孵化功能,与哈工大及中欧膜技术研究院紧密合作,主要从事环保装备研发、设计、销售、运营及智慧水务平台建设。

    全局底部横幅