博客
关于我
图解Go语言内存分配
阅读量:452 次
发布时间:2019-03-06

本文共 1552 字,大约阅读时间需要 5 分钟。

Go语言内置运行时(runtime)的内存管理机制

Go语言的内存管理机制是其运行时(runtime)的核心组成部分之一。传统的内存管理方式依赖于系统调用,这在多线程环境下会导致不少问题。Go runtime抛弃传统的内存分配方式,采用了一种自主管理的模式,实现了更高效的内存使用方式,如内存池、预分配等。这种机制避免了频繁的系统调用,提升了性能表现。

内存分配的基本原理

Go runtime在程序启动时,向操作系统申请一块内存区域(称为arena),并将其划分为三个主要区域:

  • 512MB:用于存放TLS(线程本地存储)。
  • 16GB:用于存放堆区(用于动态分配的对象)。
  • 512GB:用于存放程序的静态数据。

堆区管理

堆区是Go运行时用于动态分配的内存区域。heap区被划分为多个8KB的小块,每个小块称为page。这些page被组合成更大的管理单元,称为mspan(memory span)。mspan是一个包含多个连续page的内存块,用于分配多个对象。

每个mspan都有一个对应的记录,存储其起始地址、所包含的page数量、以及分配给对象的块数量。为了实现内存管理的高效,mspan还维护了一个位图,用于标记哪些块已经被分配。

内存管理单元

mspan是Go内存管理的基本单元。它根据对象的大小将内存划分为若干个对象块。每个mspan都有一个规格(Size Class),决定其能分配的最大对象大小。规格的划分非常重要,直接影响垃圾回收的效率。

mspan的规格划分如下:

  • Size Class:决定了mspan分配的最大对象大小。
  • Span Class:与Size Class的关系为Span Class = 2 × Size Class。每个Size Class对应两个Span Class,分别用于存放带有指针和不带指针的对象。

mspan的大小划分非常灵活,支持多种对象大小的分配需求。

内存管理组件

Go runtime中的内存管理由三大组件协同工作:

  • mcache(本地缓存):每个工作线程都有一个mcache,用于本地缓存可用的mspan资源。mcache的结构体包含所有规格大小的mspan,用于快速分配小对象。mcache的大小是NumSpanClasses的两倍,确保能够同时缓存带有指针和不带指针的对象。

  • mcentral(全局管理器):mcentral用于管理所有线程共享的mspan资源。它维护了空闲和已分配的mspan列表,支持线程间的mspan交换。mcentral的操作需要互斥锁,以确保线程安全。

  • mheap(内存池):mheap是Go程序持有的所有堆内存资源。它负责管理未切割的mspan,并向操作系统申请新内存。当mcentral无法满足分配需求时,mheap会申请更多内存。

  • 内存分配流程

    内存分配的流程根据对象的大小分为三个阶段:

  • 小对象(≤16B):这些对象通过mcache的“小分配器”直接分配,无需遍历mspan。

  • 一般对象(16B < size ≤32KB):首先确定对象的规格大小,然后从mcache中获取相应规格的mspan。如果mcache中没有可用mspan,则向mcentral申请。如果mcentral也无可用mspan,则向mheap申请。如果mheap也没有合适的mspan,则向操作系统申请内存。

  • 大对象(>32KB):大对象直接从mheap分配。

  • 总结

    Go语言的内存管理机制通过mcache、mcentral和mheap三大组件,实现了高效的内存分配和管理。其核心思想是能复用一定要复用,通过本地缓存和全局管理器,有效减少了内存碎片和系统调用开销。这一机制在多线程环境下表现尤为出色,为Go语言的高性能提供了坚实基础。

    转载地址:http://hiffz.baihongyu.com/

    你可能感兴趣的文章
    Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
    查看>>
    Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
    查看>>
    Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
    查看>>
    Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    Openlayers高级交互(2/20):清除所有图层的有效方法
    查看>>
    Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
    查看>>
    Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
    查看>>
    Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
    查看>>
    Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
    查看>>
    Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
    查看>>
    Openlayers高级交互(7/20):点击某点弹出窗口,自动播放视频
    查看>>
    Openlayers高级交互(8/20):选取feature,平移feature
    查看>>
    Openlayers高级交互(9/20):编辑图形(放缩、平移、变形、旋转),停止编辑
    查看>>
    Openlayers:DMS-DD坐标形式互相转换
    查看>>
    openlayers:圆孔相机根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域
    查看>>
    OpenLDAP(2.4.3x)服务器搭建及配置说明
    查看>>
    OpenLDAP编译安装及配置
    查看>>
    Openmax IL (二)Android多媒体编解码Component
    查看>>
    OpenMCU(一):STM32F407 FreeRTOS移植
    查看>>