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

    你可能感兴趣的文章
    Node-RED中使用JSON数据建立web网站
    查看>>
    Node-RED中使用json节点解析JSON数据
    查看>>
    Node-RED中使用node-random节点来实现随机数在折线图中显示
    查看>>
    Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
    查看>>
    Node-RED中使用Notification元件显示警告讯息框(温度过高提示)
    查看>>
    Node-RED中实现HTML表单提交和获取提交的内容
    查看>>
    Node.js 函数是什么样的?
    查看>>
    Node.js 历史
    查看>>
    Node.js 在个推的微服务实践:基于容器的一站式命令行工具链
    查看>>
    Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
    查看>>
    node.js 怎么新建一个站点端口
    查看>>
    Node.js 文件系统的各种用法和常见场景
    查看>>
    node.js 简易聊天室
    查看>>
    node.js 配置首页打开页面
    查看>>
    node.js+react写的一个登录注册 demo测试
    查看>>
    Node.js中环境变量process.env详解
    查看>>
    Node.js卸载超详细步骤(附图文讲解)
    查看>>
    Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
    查看>>
    Node.js安装及环境配置之Windows篇
    查看>>
    Node.js安装和入门 - 2行代码让你能够启动一个Server
    查看>>