谈论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?内容请搜索完美下载以前的文章或继续浏览下面的相关文章希望大家以后多多支持完美下载!

    全局中部横幅
    135编辑器官网

    135编辑器是一款提供微信公众号文章排版和内容编辑的在线工具,样式丰富,支持秒刷、收藏样式和颜色、图片素材编辑、图片水印、一键排版等功能,轻松编辑微信公众号图文。

    康立民生官网【恒达百业有限公司旗下品牌】

    康立民生将在民生与健康领域不断为人类提供优质的产品和完善的服务,竭力改善大众生活品质与健康状况是我们一直以来的品牌核心价值观和企业的行为动力。

    中国台湾网

    中国台湾网是中央台办和国台办管理的国家重点新闻网站,拥有庞大的涉台资源。全面报道台湾事务和两岸关系的重要新闻资讯,致力于传播两岸亲情,沟通两岸民意,服务两岸交流,是两岸网络信息枢纽和同胞交流互动平台。

    学车

    众悦学车网是国内专业的考驾照及驾校查询平台,提供驾校查询、驾校点评、驾校考试、驾校口碑,驾校投诉等驾考服务;实时权威的交规模拟考试,驾考秘籍,技巧视频,学车小游戏;交规模拟考试app免费下载。

    单级多级滑触线

    上海天皋电气有限公司主要生产销售供安全,行车,管式,移动,单极,钢体,无接缝,天车200A滑触线,300A滑触线,500A滑触线,800A滑触线,多极滑触线,单极滑触线,导电滑触线等,要问集电器,价格,型号,规格,哪家好?我们是专业滑触线生产厂家.

    结晶器填充料,耐火捣打料浇注料可塑料,成型套砖

    巩义市金牛耐火材料厂是致力于有色金属加工铜,铝,锌感应电炉耐火材料加工及辅助耐火材料的厂家,生产把关严,出厂让客户放心。产品有:硅质捣打料、复合硅质捣打料、高铝复合捣打料、特种材料捣打料、铝镁捣打料、刚玉可塑料、莫来石浇注料、低水泥浇注料、轻质浇注料、辅助耐火材料、高强耐火泥、线圈胶泥、修补料,配套各种耐火砖、电炉所用的辅助材料。咨询电话:15137151612

    苏州茏测检测技术服务有限公司

    高加速寿命检测|HALT/HASS检测|应力型变量检测|气体腐蚀检测|振动检测|IP外壳防护检测|ISTA包装运输检测|UV紫外光老化检测

    版权桥

    Out-of-the-boxmid-stagefront-end/designsolution.

    河北诚鑫价格评估

    河北诚鑫价格评估有限公司廊坊专业快速办理机设设备,土地房屋,机动车辆,林产林权,无形资产评估及其他资产价格评估等业务,咨询热线13832643699赵经理

    谱足成语网

    探索成语的哲理智慧和文化底蕴,领悟其中的生活智慧和人生哲理,让你的人生更加丰富和有意义。

    苏州泰鼎智能科技有限公司

    苏州泰鼎智能科技有限公司【热线:0512-63103162】产品涵盖18650锂电池组,21700锂电池组,扫地机器人电池包,BMS和软包电芯三大体系,坚持以客户为中心,以“严谨诚信,务实创新,以人为本,心存感恩”为核心价值观,坚持技术创新,管理创新,希望与各领域的客户一起携手创造未来!

    新乡手机靓号

    新乡手机靓号提供各种优质手机号码,出售回收新乡手机靓号18837300098,立即挑选您的专属靓号!满足您的个性化需求。

    全局底部横幅