Go内存模型

本文探讨了Go语言的内存管理,包括栈、堆和固定大小对象的分配。Go程序员通常无需关心变量在堆还是栈上的分配。文章详细介绍了Goroutine的栈管理,包括初始2K的栈大小、栈增长的morestack机制,以及从栈pool和stackcache进行分配。此外,还讨论了栈增长的连续栈和分离栈技术。对于堆内存,文章解释了三级管理组件(Cache、Central、Heap)的工作原理和内存回收策略。最后,提到了变量逃逸分析在决定变量分配位置中的作用。
摘要由CSDN通过智能技术生成

链客,专为开发者而生,有问必答!

此文章来自区块链技术社区,未经允许拒绝转载。
在这里插入图片描述
Go的内存管理话题很大,一边学习,一边记录,持续更新。

提纲挈领
和C、C++不同,一般来说,Go程序员无需关心变量是在堆上还是在栈上。

Go语言中内存分配大致有3种模式:Stack、Heap、Fixed Size Segment。


栈的概念类似传统Linux下C、C++的概念,即通过栈顶指针移动来分配内存。一般用来存储局部变量、函数参数等。每个Goroutine都有自己的执行栈,互相独立,无需加锁。Goroutine的栈是从Heap中分配的,如果运行中栈需要扩展,会使用连续栈技术进行扩展(通过Heap的操作---- allocate new,copy old to new,free old)。

Goroutine中的栈很小,初始只有2K,因此创建代价很小。

堆和GC
Go语言支持GC,针对堆中的对象。因此,它在分配内存时需要着重考虑如下两个问题:

如何平衡内存分配效率和内存利用率?
如何支持快速的GC迭代,不对业务造成较大冲击?
同时,由于堆是所有Goroutine共有的,因此需要加锁,后面详解中可以观察下它是如何优化这个问题的。

具体到实现上,Go采用了类似tmalloc的做法,在系统调用上封装了一层,减少直接系统调用的性能损耗;同时,会定期扫描释放长时间不使用的空闲内存。具体实现技巧,详见下文。

垃圾回收扫描会STW,从Go1.5起,不会超过执行时间的1/5(eg. 10ms of 50ms execution)。回收时只扫描堆上的对象,但如果对象在栈上有引用,也会分析栈上对应变量,具体如下文。

The garbage collector has to be aware of both heap and stack allocated items. This is easy to see if you consider a heap allocated item, H, referenced by a stack allocated item, S. Clearly, the garbage collector cannot free H until S is freed and so the garbage collector must be aware of lifetime of S, the stack allocated item.

固定大小对象分配
顾名思义,固定大小内存分配器。一般用作,内存管理对象的分配和回收,如mspan、mcache、mcentral等;另外也被用来分配data segment和code segment。在运行期内,data segment的大小不能变化,因此,动态内存对象不能在data segment内分配。

Fixed sized segments are defined at compile time and do not change size at runtime. Read-write fixed size segments (e.g., the data segment) contain global variables while read-only segments (e.g., code segment and rodata segment) contain constant values and instructions.

性能优化
使用runtime/pprof和go tool pprof采样分析,如果growslices和newobject调用占用很多,即可考虑内存方面的优化 ---- 减少堆上分配(变量逃逸),增加栈上分配。

Reuse memory you’ve already allocated.
Restructure your code so the compiler can make stack allocations instead of heap allocations. Use go tool compile -m to help you identify escaped variables that will be heap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值