初探Golang内存管理和垃圾回收机制

内存管理

堆与栈

Go语言与CPP类似,也有栈和堆的概念,栈就是函数使用的栈,函数局部变量都在栈里,而new出来的变量大部分在堆上,当然这还取决于变量是会在作用域外被使用(注:编译器通过静态分析技术Escape Analysis来确定变量的作用范围)。

堆内存管理机制

Go的内存管理是基于tcmalloc实现的,tcmalloc核心思想是多级缓存、定长分配和管理.

参考文章

Golang内存管理

垃圾回收GC

常用GC算法

Golang的三色标注-清除法

Golang 垃圾回收剖析

Unlike GHC’s stop-the-world collector, Go’s collector runs concurrently with the program to achieve short GC pauses.it means that the pause times become a scheduling problem.

In practice, the pause times of these phases to be <1ms with very large heaps. With a concurrent GC, there is also potential for running the GC in parallel on multiple processors.

Low latency has costs. The most important cost is reduced throughput. Concurrency requires extra work for synchronization and duplication, which eats into the time the program can be doing useful work. GHC’s garbage collector is optimized for throughput, but Go’s is optimized for latency. At Pusher, we care about latency, so this is an excellent tradeoff for us.

A second cost of concurrent garbage collection is unpredictable heap growth. The program can allocate arbitrary amounts of memory while the GC is running. This means the GC must be run before the heap reaches the target maximum size.

GC times tend to be proportional to the number of pointers rather than the number of bytes. we would expect pauses of around 1ms for our heap size of 200MB, according to the go team. The heap size is kept large, which is important because the heap must be traversed in order to detect which objects are still referenced. This is why GC running time is proportional to the number of live objects/pointers between them.

go tool trace observe gc phase state.

参考链接

  1. ptmalloc/tcmalloc/jemalloc内存分配策略
  2. Golang’s Real-time GC in Theory and Practice
  3. Recycling memory buffers in Go