简介
本文只用说明heap报表中字段的信息,并且写了python小脚本来分析heap中的内存使用情况。
如何阅读heap信息
golang中的MemStats数据结构是用于描述当前进程的内存消耗值。
概要统计信息
Alloc 分配给heap对象的内存大小。这个值和HeapAlloc相同。
TotalAlloc 累计分配给heap对象的内存大小。它的增长和Alloc是一样的,但是不会随着对象释放而降低。
Sys 从OS获取的全部内存大小。这个值就是下面XSys
值的总和。Sys度量被Go的运行时使用的一些虚拟地址空间,用于存储heap,stacks,和其他的内部数据结构。 虚拟内存不会真实的分配物理内存,虽然通常这一切是在某个时刻发生。
Lookups 处理runtime时候使用的指针数量。通常用于运行时调试之用。
Mallocs 累计分配heap对象个数。还存活的对象数量就是Mallocs - Frees
Frees 累计释放heap对象个数。
堆统计信息
简介信息
介绍一些Go如何组织内存。如果是>32k的内存将会直接使用系统的内存分配和释放。Go分割heap的虚拟内存到spans
,这种内存是连续区域的内存大小在8k或者更加大。一个span
可能有下列3中状态:
idle
容器中没有任何的对象或者数据。idle span背后的物理内存能被释放还给OS(但是虚拟地址空间并不会这么做),或者能被转换成in use
或者stack
span。
in use
至少含有一个heap对象而且可能含有空闲的空间提供分配给heap对象。
stack
span 提供给了goroutine 栈使用。栈span不会被视为堆的一部分。span可以被当成heap或者stack内存;但是不可能同时用于两种。
细则
HeapAlloc heap对象分配时使用的内存大小。分配的heap对象包含一切能被引用的的对象,也包含没有被引用还没有被GC回收的对象。特别的,HeapAlloc增长时伴随着heap对象的分配,降低时伴随heap内存清理和没被引用的对象被回收。清理渐进的发生于GC周期,所以二者处理都是同时在进行中,最终HeapAlloc的结果趋近于平滑(于之形成对比的锯齿的情况,发生在stop-the-world内存回收过程)。
HeapSys heap对象从OS分配内存空间。HeapSys度量的是heap使用的虚拟内存空间。这些虚拟机空间已经被分配,但是没有使用,这样的情况将不会消耗任何的物理内存,但是它变成未使用时(阅读等下将提到的HeapReleased量),当值将会变小,这种情况发生在虚拟内存对应的物理内存归还给OS。
HeapIdle idle spans的空间。里面没有任何的对象,这些span可以(或者已经)被归还给OS,或者他们可能被提供给heap分配器接着来分配,或者也可以提供给stack做内存。HeapIdle减去HeapReleased就等于将会归还给OS的空间,但是这块空间可能被runtime利用,以便于heap变大时候,无需再次从OS中申请更多内存。如果这个差值大于heap大小,预示着最近有一次瞬时的实时堆大小达到的峰值。
HeapInuse in-use
spans占用的空间大小。至少有一个对象在这里。这种span只能被用于相同的内存尺寸对象的分配。HeapInuse-HeapAlloc等于当前还可以分配给特定尺寸对象内存量,但目前尚未使用到。这个是内存碎片的上限,但是通常这么做能更加高效的复用。
HeapReleased 归还给操作系统的物理内存。从idle spans归还给操作系统的总数内存块,尚未为堆重新获取。
HeapObjects 当前分配的heap对象数目。和HeapAlloc相似,此值增减发生在对象分配和堆整理而且不可达对象的清理。
栈信息
堆和栈内存是互相独立的,在go运行时中,能将二者的内存互相转换。
细则
StackInuse 栈spans中使用全部内存块
StackSys 栈从OS中获取的内存块。StackSys是StackInuse加上少量直接从系统获取的空间为系统级线程的栈。
非堆栈内存信息
下面部分是运行时内部的数据结构的内存使用情况,未从堆内存分配的结构(通常是因为它们是实现堆的一部分)。不像堆或者栈内存,这种内存有专属的数据结构。
这些内存主要用于调试运行时内存。
细则
MSpanInuse / MSpanSys 分配mspan的内存,从系统中获取的空间。
MCacheInuse / MCacheSys 分配mcache的内存,从系统中获取的空间。
BuckHashSys 分析hash桶表大小。
GCSys gc元数据。
OtherSys 杂项。
为了方便,我写了一个读取的脚本。源码下载地址
这里我分析了一份内存:
1 | 概要信息 |
参考
[1] 实时监控heap使用情况的工具
[2] go-echat直接使用go绘图