博客
关于我
图解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/

    你可能感兴趣的文章
    【Docker知识】重定向 Docker 的根目录
    查看>>
    Openstack企业级云计算实战第二、三期培训即将开始
    查看>>
    OpenStack创建虚拟机实例实战
    查看>>
    OpenStack安装部署实战
    查看>>
    OpenStack实践系列⑨云硬盘服务Cinder
    查看>>
    OpenStack架构
    查看>>
    OpenStack版本升级与故障排查实战
    查看>>
    Openstack的HA解决方案【替换原有的dashboard】
    查看>>
    OpenStack的基本概念与架构详解
    查看>>
    Openstack的视频学习
    查看>>
    OpenStack自动化安装部署实战(附OpenStack实验环境)
    查看>>
    openstack虚拟机迁移live-migration中libvirt配置
    查看>>
    OpenStack项目管理实战
    查看>>
    OpenStreetMap初探(一)——了解OpenStreetMap
    查看>>
    openSUSE 13.1 Milestone 2 发布
    查看>>
    openSUSE推出独立 GUI 包管理工具:YQPkg,简化了整个软件包管理流程
    查看>>
    OpenVP共用账号 一个账号多台电脑登录
    查看>>
    OpenVSwtich(OVS)Vlan间路由实战 附实验环境
    查看>>
    Openwrt LuCI模块练习详细步骤
    查看>>
    openwrt_git_pull命令提示merger冲突时如何解决?
    查看>>