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


    本文地址: https://www.gpxz.com/article/f10fd3e11ae4b48d400d.html
    全局中部横幅
    全局中部横幅
    威宁彝族回族苗族自治县人民医院

    威宁彝族回族苗族自治县人民医院|威宁县人民医院【官网】

    拼多多商家后台

    拼多多-社交电商引领者,官方入驻平台,0元开店1分钟入驻。开网店就选拼多多,新电商新机遇。社交电商流量红利期,获客成本超低,抢占巨额流量入口极速打造爆款。拼多多商家后台,全流程开店教程,从新手入门到进阶玩法,手把手教你开网店,已经有上千万卖家在拼多多入驻赚钱了。入驻、上新、货源、客服、物流、售后,一切问题在拼多多都迎刃而解。海量资源位,超多无门槛活动,新店老店都能上。超多店铺营销推广工具,新手开店不怕没客源。专属对接小二,帮你解决店铺运营困惑。

    Qt大课堂

    本站名称“Qt大课堂-传播分享Qt知识的平台”,英文名称“QtShare”,开通于2018年4月,主要记录平常工作、学习的Qt技术,分享传播知识

    世科网

    世科网,首家基于技术壁垒为核心的互动营销一站式商务服务平台。提供快速、实用、全面、专业的技术壁垒(TBT)、检测认证领域信息与服务。网站收录国内外权威检测认证机构、实验室,科研机构,质量诚信供应商以及技术成果和标准产品库。助力应对全球技术性贸易壁垒,开拓国际市场!

    四川消防设备厂家

    四川消防设备批发厂家就找攀枝花市仁和区正立消防器材销售部专门从事四川消防灭火器,四川火灾报警设备,四川避难逃生设备等四川消防器材销售以及四川保安器材,四川交通设施批发.我司一直都秉承客户至上/品质为首的理念,多年来成功为各界伙伴提供了优良的产品和服务,获得广大客户的认可和好评,如果您有合作意向欢迎来电联系我司!

    赵县123信息网

    赵县123信息网-赵县分类信息网大全是领先的赵县免费发布信息平台和赵县信息港,随时免费发布赵县生活信息包括求职招聘信息、房产信息、征婚交友、二手交易、生活服务、贷款信息等,是赵县百姓城市生活中不可缺少的赵县信息港和赵县贴吧.

    淮南市利升工贸有限责任公司

    煤矿井下用塑料编织袋|全螺纹式玻璃钢锚杆|托辊|复合片二翼钻头|法兰盘|无缝钢管|螺旋焊管

    生物质燃烧机

    廊坊德迈尔环保设备有限公司主营:生物质颗粒燃烧机,生物质燃烧机,木片燃烧机。热线电话:15803164088。

    联系我们果博东方电话19048888886

    果博东方又名(福布斯)果博东方客服开户电话1904-8888886和(0883-6989999)开户-上分-上分注册-官网(fbs6888.com)第一步打开果博官网,第二步注册后输入账号,【果博娱乐

    厦门市佳庆网络科技有限公司

    厦门市佳庆网络科技有限公司【咨询电话:18020726693】,公司主营厦门网站优化,厦门站群优化,厦门网站建设,厦门网站推广,厦门小程序开发,厦门谷歌推广,微信朋友圈推广公司已成为腾讯企业邮箱的品牌代理商。

    
    全局底部横幅