城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

一文弄清楚Golang内存逃逸

1月5日 夜如影投稿
  1。为什么要了解内存逃逸
  cc的programmer对于堆内存、栈内存一定非常熟悉,以为内存管理完全由使用者自己管理。Go语言的内存管理完全由Go的runtime接管,那么是不程序员就完全不用care变量是如何分配的呢?减少了gc压力。如果变量都分配到堆上,堆不像栈可以自动清理。它会引起Go频繁地进行垃圾回收,而垃圾回收会占用比较大的系统开销,甚至会导致STW(stoptheworld)。提高分配效率。堆和栈相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片。栈内存分配则会非常快。但当我们的服务发现性能瓶颈,要如何去定位瓶颈,让我们的程序运行的更快,就非常有必要了解Go的内存分配。2。什么是内存逃逸
  Go语言中局部的非指针变量通常是不受GC管理的,这种Go变量的内存分配称为栈分配,处于goroutine自己的栈中。由于Go编译器无法确定其生命周期,因此无法以这种方式分配内存的Go变量会逃逸到堆上,被称为内存逃逸。3。哪些情况下会发生内存逃逸
  先来说一下通过go编译器查看内存逃逸方式gobuildgcflagsmxxx。go局部变量被返回造成逃逸packagemaintypeUserstruct{Namestring}funcfoo(sstring)User{u:new(User)u。Namesreturnu方法内局部变量返回,逃逸}funcmain(){user:foo(hui)user。Namedev}commandlinearguments。escape。go:7:6:caninlinefoo。escape。go:13:6:caninlinemain。escape。go:14:13:inliningcalltofoo。escape。go:7:10:leakingparam:s。escape。go:8:10:new(User)escapestoheap。escape。go:14:13:new(User)doesnotescapeinterface{}动态类型逃逸packagemainimportfmtfuncmain(){name:devhuifmt。Println(name)}commandlinearguments。escape02。go:7:13:inliningcalltofmt。Println。escape02。go:7:13:nameescapestoheap。escape02。go:7:13:〔〕interface{}{。。。}doesnotescape:1:leakingparamcontent:。this
  很多函数的参数为interface{}空接口类型,这些都会造成逃逸。比如funcPrintf(formatstring,a。。。interface{})(nint,errerror)funcSprintf(formatstring,a。。。interface{})stringfuncFprint(wio。Writer,a。。。interface{})(nint,errerror)funcPrint(a。。。interface{})(nint,errerror)funcPrintln(a。。。interface{})(nint,errerror)复制代码
  编译期间很难确定其参数的具体类型,也能产生逃逸funcmain(){fmt。Println(hello逃逸)}逃逸日志分析。main。go:5:6:caninlinemain。main。go:6:13:inliningcalltofmt。Println。main。go:6:14:hello逃逸escapestoheap。main。go:6:13:〔〕interface{}literaldoesnotescape栈空间不足逃逸packagemainfuncmain(){s:make(〔〕int,1000,1000)forindex,:ranges{s〔index〕indexs1:make(〔〕int,10000,10000)forindex,:ranges1{s1〔index〕index}}
  逃逸分析:。escape03。go:4:11:make(〔〕int,1000,1000)doesnotescape。escape03。go:9:12:make(〔〕int,10000,10000)escapestoheap
  s足够在栈空间分配没有逃逸;s1空间不够在栈内分配发生了逃逸。变量大小不确定(如slice长度或容量不定)packagemainfuncmain(){s:make(〔〕int,0,1000)forindex,:ranges{s〔index〕index}num:1000s1:make(〔〕int,0,num)forindex,:ranges1{s1〔index〕index}}
  逃逸分析:。escape05。go:4:11:make(〔〕int,0,1000)doesnotescape。escape05。go:10:12:make(〔〕int,0,num)escapestoheap
  s分配时cap是一个常量没有发生逃逸,s1的cap是一个变量发生了逃逸。闭包funcIncrease()func()int{n:0returnfunc()int{nreturnn}}funcmain(){in:Increase()fmt。Println(in())1fmt。Println(in())2}。escape04。go:6:2:movedtoheap:n。escape04。go:7:9:funcliteralescapestoheap。escape04。go:7:9:funcliteraldoesnotescape。escape04。go:15:16:int(R0)escapestoheap。escape04。go:15:13:〔〕interface{}{。。。}doesnotescape。escape04。go:16:16:int(R0)escapestoheap。escape04。go:16:13:〔〕interface{}{。。。}doesnotescape:1:leakingparamcontent:。this4。如何减少逃逸局部切片尽可能确定长度或容量benchmarktestimporttestingsliceEscape发生逃逸,在堆上申请切片funcsliceEscape(){number:10s1:make(〔〕int,0,number)fori:0;i{s1append(s1,i)}}sliceNoEscape不逃逸,限制在栈上funcsliceNoEscape(){s1:make(〔〕int,0,10)fori:0;i10;i{s1append(s1,i)}}funcBenchmarkSliceEscape(btesting。B){fori:0;ib。N;i{sliceEscape()}}funcBenchmarkSliceNoEscape(btesting。B){fori:0;ib。N;i{sliceNoEscape()}}测试结果:BenchmarkSliceEscapeBenchmarkSliceEscape105327151322。09nsopBenchmarkSliceNoEscapeBenchmarkSliceNoEscape101870331116。458nsop合理选择返回值、返回指针返回指针可以避免值的拷贝,但是会导致内存分配逃逸到堆中,增加GC的负担。一般情况下,对于需要修改原对象,或占用内存比较大的对象,返回指针。对于只读或占用内存较小的对象,返回值能够获得更好的性能。benchmarktestpackageescapebench02importtestingtypeStstruct{arr〔100〕int}funcretValue()St{varstStreturnst}funcretPtr()St{varstStreturnst}funcBenchmarkRetValue(btesting。B){fori:0;ib。N;i{retValue()}}funcBenchmarkRetPtr(btesting。B){fori:0;ib。N;i{retPtr()}}测试结果BenchmarkRetValue103471442434。45nsop0Bop0allocsopBenchmarkRetPtr108038676145。3nsop896Bop1allocsop
  可以看到返回值更快且没有发生堆内存的分配。小的拷贝好过引用benchmarktestpackageescapebench03importtestingconstcapacity1024funcarrayFibonacci()〔capacity〕int{vard〔capacity〕intfori:0;ilen(d);i{ifi1{d〔i〕1continue}d〔i〕d〔i1〕d〔i2〕}returnd}funcsliceFibonacci()〔〕int{d:make(〔〕int,capacity)fori:0;ilen(d);i{ifi1{d〔i〕1continue}d〔i〕d〔i1〕d〔i2〕}returnd}funcBenchmarkArray(btesting。B){fori:0;ib。N;i{arrayFibonacci()}}funcBenchmarkSlice(btesting。B){fori:0;ib。N;i{sliceFibonacci()}}测试结果:BenchmarkArray103461102986nsop0Bop0allocsopBenchmarkSlice103897452849nsop8192Bop1allocsop
  那么多大的变量才算是小变量呢?对Go编译器而言,超过一定大小的局部变量将逃逸到堆上,不同Go版本的大小限制可能不一样。一般是64KB,局部变量将不会逃逸到堆上。返回值使用确定的类型benchmarktestpackageescapebench04importtestingconstcapacity1024funcreturnArray()〔capacity〕int{vararr〔capacity〕intfori:0;ilen(arr);i{arr〔i〕1000}returnarr}funcreturnInterface()interface{}{vararr〔capacity〕intfori:0;ilen(arr);i{arr〔i〕1000}returnarr}funcBenchmarkReturnArray(btesting。B){fori:0;ib。N;i{returnArray()}}funcBenchmarkReturnInterface(btesting。B){fori:0;ib。N;i{returnInterface()}}测试结果
投诉 评论 转载

如果你很穷,你会生第二胎吗?我现在不打算生二胎,我的想法是优生优育,我不太明白,为什么越穷的人越生,越生越穷。我家里只有我自己带孩子,老公也经常不在家,一个月在家的时间很难超过10天,他也想多陪陪我……蒋碧微病发厌夫症的隐因在苦闷贫穷的日子,徐先生只管一人吃饱有许多婚姻的失败和冷淡,并不完全因为某一方出轨了,亦或是感情淡了。前者出轨除了性冲动、头脑发热犯下大错之外,大多是由于后者感情淡了才出轨。而后者感情淡了,几乎是一个有悖正常思维……金庸笔下,哪位高手破得了独孤九剑?金庸武侠中,高深的武功大体可以分成四类:内功、掌法、指法、剑法。在金庸武侠作品中,刀法始终上不了台面,绝世高手要么是赤手空拳不用兵器,要么是手持三尺青锋,一剑光寒十四州。……北京昨日新增本土5091139,含328例社会面11月23日0时至24时,北京新增509例本土确诊病例和1139例无症状感染者(含37例无症状感染者转确诊病例,其中913例已通报),1283例隔离观察人员、328例社会面筛查……如果你所在的单位会计与出纳工资一样多,你怎么看?这个还是要看工作内容及工作强度才能确定。一般企业中会计和出纳的工作比例是不一样的,一般是报销单据到会计,会计根据制度规定出据会计凭证后再转给出纳,报销人在出纳那取现金等。就这一……大数据扫黄如何自动给你打上标签,让你成为重点观察对象提到黄赌毒,很多人都说与赌毒不共戴天。反正满嘴不提黄。网络空间中,是否某个夜晚,无处安眠的你,偷偷打开某个网站。而如今网络数据越来越高端化,无论你是通过什么手段也难逃大数据扫黄……日本姓氏的由来可能还真不是笑谈,夜爬文化还真可能解释这些姓氏中国人对日本的仇恨是有血脉传承的,这种仇恨来自于背叛和毫无人性的屠杀,所以在中国调侃日本人是一个最没有负担的话题,任何国人在面对日本这个民族的时候都会不自觉的同仇敌忾,之前在网……焦点访谈会师空间站圆梦启新程神舟十五号乘组已经在轨超过了一周,费俊龙、邓清明、张陆三名航天员投入到正式的工作和锻炼中。和此前所有的航天员相比,他们是非常幸运的一个乘组。因为以往中国航天员每次到太空出差,迎……一文弄清楚Golang内存逃逸1。为什么要了解内存逃逸cc的programmer对于堆内存、栈内存一定非常熟悉,以为内存管理完全由使用者自己管理。Go语言的内存管理完全由Go的runtime接管,那么……金融新基建丨券商发力机构业务平台化建设,开放证券还有多远?21世纪经济报道记者李览青上海报道在零售经纪业务向机构经纪业务的转型潮流中,券商的开放生态正在形成。据中证协2021年数据显示,77家证券公司将数字化转型列为公司发……陈毅去世13年后,江西农妇称自己是陈毅妻子,蔡畅终于找到你了1985年6月,在陈毅元帅去世13年后,曾任全国妇联主席的蔡畅,突然收到了一封来自江西的信。这封信是一个叫赖月明的农妇写的,她自称为陈毅的妻子,此时在江西的农村生活,她写……苏州一女子生下三胞胎却拥有3个不同的爹,丈夫的肺都被气炸了三个孩子拥有三个爹,令人不解的是这三个孩子是一名女子生下的三胞胎。前段时间在江苏省苏州市发生了一件令人匪夷所思的事情。阿伟(化名)和阿丽(化名)是在相亲时候认识的,……
我想知道CBA篮球各个篮球队靠什么挣钱?打赢了或者总冠军都是为什么有的农民工说宁愿饿死也不愿帮亲戚打工呢?刘禅,被冤枉了一千多年的好皇帝美国少年帮助连环杀手奸杀数十名男孩,之后良心发现将凶手击毙2023款起亚K5GT曝光!2。5T10AT299马力,大众险!电动车竟在骑行中起火!一日一城一徽章赫尔松光伏硅料行业研究光伏产业链的黑金,双碳时代拥硅为王人类历史上的最大规模空战,一举打破德国空军不可战胜的神话聚焦云南省人民政府关于2022年度云南省有突出贡献优秀专业技你知道清朝共有多少年的历史吗?(一)同比增长36。6!潍坊港这项业务做大做强
大学生网赚做什么好?大学生最适合的三种网赚小学音乐教学工作总结广东名菜南乳鸡翅,一口下去鸡肉鲜嫩脱骨,好吃又解馋偷听企业人力资源管理的创新发展策略探讨冬日偶书新宅徐州东区2890亩征迁改造地块,最新示意图曝光!《DoctorX》米仓凉子不出错的成熟干练穿搭B2B电子邮件营销方法与技巧年党委理论学习中心组学习总结企业支出管理赛道独角兽:分贝通完成DST领投C轮1。4亿美元

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁