diff --git a/README.md b/README.md index def6a9f..db5e5bc 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,82 @@ -# XMM (eXtensible) Memory Manager - 完全自主第三方Go内存分配管理器 -
-
+# XMM (eXtensible) Memory Manager - 完全自主第三方 Go 内存分配管理器 -## XMM是什么? +- [XMM (eXtensible) Memory Manager - 完全自主第三方 Go 内存分配管理器](#xmm-extensible-memory-manager---完全自主第三方-go-内存分配管理器) + - [XMM 是什么?](#xmm-是什么) + - [XMM 主要具备以下特点](#xmm-主要具备以下特点) + - [为什么要设计 XMM?](#为什么要设计-xmm) + - [为什么要设计自主的内存管理器?](#为什么要设计自主的内存管理器) + - [为什么不使用内置的 map/slice 等数据结构?](#为什么不使用内置的-mapslice-等数据结构) + - [为什么不使用其他开源的内存池?](#为什么不使用其他开源的内存池) + - [XMM 的最终设计结论是什么?](#xmm-的最终设计结论是什么) + - [XMM 设计的目标是什么?](#xmm-设计的目标是什么) + - [XMM 快速使用入门](#xmm-快速使用入门) + - [☆ XMM 使用案例 ☆](#-xmm-使用案例-) + - [XMM 实现原理介绍](#xmm-实现原理介绍) + - [XMM 技术交流](#xmm-技术交流) -XMM - X(eXtensible) Memory Manager(完全自主研发的第三方Go内存分配管理器) +## XMM 是什么? -XMM是一个在Go语言环境中完全自主实现的第三方内存管理库,不依赖于Go本身的任何内存管理能力,纯自主实现的Go内存管理库;能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建(链表/数组/树/hash等场景),能够良好完美的逃逸掉Go内置的GC机制,保证程序的超高性能,是构建高性能程序基础设施。 +XMM - X(eXtensible) Memory Manager(完全自主研发的第三方 Go 内存分配管理器) + +XMM 是一个在 Go 语言环境中完全自主实现的第三方内存管理库,不依赖于 Go 本身的任何内存管理能力,纯自主实现的 Go 内存管理库;能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建(链表/数组/树/hash 等场景),能够良好完美的逃逸掉 Go 内置的 GC 机制,保证程序的超高性能,是构建高性能程序基础设施。
-#### XMM主要具备以下特点: -1. XMM是一个在Go语言环境中完全自主实现的第三方内存管理库,不依赖于Go本身的任何内存管理能力,通过6000行纯Go代码自主实现的Go内存管理库,适合不用Go的GC想要自己管理内存的场景。 +### XMM 主要具备以下特点 + +1. XMM 是一个在 Go 语言环境中完全自主实现的第三方内存管理库,不依赖于 Go 本身的任何内存管理能力,通过 6000 行纯 Go 代码自主实现的 Go 内存管理库,适合不用 Go 的 GC 想要自己管理内存的场景。 -2. XMM能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建,比如链表/数组/树/哈希表等等场景;XMM可以让你像C/C++一样方便便捷使用系统内存,并且不用担心性能问题。 +2. XMM 能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建,比如链表/数组/树/哈希表等等场景;XMM 可以让你像 C/C++ 一样方便便捷使用系统内存,并且不用担心性能问题。 -3. XMM能够良好完美的逃逸掉Go内置的GC机制,保证程序的超高性能,是构建高性能程序基础设施;但与sync.Pool等实现机制完全不同,sync.Pool等使用字节流实现来逃逸GC,XMM是纯使用Linux系统的mmap作为底层内存存储,XMM更像 TcMalloc 等内存分配器。 +3. XMM 能够良好完美的逃逸掉 Go 内置的 GC 机制,保证程序的超高性能,是构建高性能程序基础设施;但与 sync.Pool 等实现机制完全不同,sync.Pool 等使用字节流实现来逃逸 GC,XMM 是纯使用 Linux 系统的 mmap 作为底层内存存储,XMM 更像 TcMalloc 等内存分配器。 -4. XMM协程安全,且分配性能超高,目前在普通Linux服务器上面可以达到 350w alloc/s,就是每秒可以进行350万次的内存分配操作不卡顿,非常适合想要自主管理内存且超高性能场景。 +4. XMM 协程安全,且分配性能超高,目前在普通 Linux 服务器上面可以达到 350w alloc/s,就是每秒可以进行 350 万次的内存分配操作不卡顿,非常适合想要自主管理内存且超高性能场景。 -5. XMM内存库使用接口简单,兼容性强,能够兼容Go 1.8 以上版本,容易上手(推荐 go 1.12+版本更好),可以在XMM之上重构你所有想要的高性能数据结构,比如 map/slice 等等。(案例部分可以做一些数据结构实现的参考) +5. XMM 内存库使用接口简单,兼容性强,能够兼容 Go 1.8 以上版本,容易上手(推荐 go 1.12+ 版本更好),可以在 XMM 之上重构你所有想要的高性能数据结构,比如 map/slice 等等。(案例部分可以做一些数据结构实现的参考)

-## 为什么要设计XMM? +## 为什么要设计 XMM? +
-#### 为什么要设计自主的内存管理器? +### 为什么要设计自主的内存管理器? -为了应对在多种内存管理的场景下的使用,可能需要有一些除了内置数据结构外的一些内存自主调度使用的场景,比如构建复杂的高性能的数据结构,在大规模内存占用,或者是非常多的小内存块占用场景下,能够尽量减少Go的GC机制,保障服务性能稳定不会因为GC而产生抖动。 +为了应对在多种内存管理的场景下的使用,可能需要有一些除了内置数据结构外的一些内存自主调度使用的场景,比如构建复杂的高性能的数据结构,在大规模内存占用,或者是非常多的小内存块占用场景下,能够尽量减少 Go 的 GC 机制,保障服务性能稳定不会因为 GC 而产生抖动。
-#### 为什么不使用内置的 map/slice 等数据结构? +### 为什么不使用内置的 map/slice 等数据结构? -Golang本身为了性能和内存可控,整个内存管理是完全封闭不对外的,并且有自主的Gc机制,需要自主内存管理比较麻烦;Go中自带的Gc机制经过很多个版本的迭代,到目前性能已经很不错,但是在大规模的碎片化内存块下面,GC还是会有一定损耗,在极端高性能场景下,GC会让整个后台应用服务性能上不去(或偶尔卡顿)。所以一句话,Go本身指针等还有性能会受到GC的影响,导致服务性能总是上不去。 +Golang 本身为了性能和内存可控,整个内存管理是完全封闭不对外的,并且有自主的 GC 机制,需要自主内存管理比较麻烦;Go 中自带的 GC 机制经过很多个版本的迭代,到目前性能已经很不错,但是在大规模的碎片化内存块下面,GC 还是会有一定损耗,在极端高性能场景下,GC 会让整个后台应用服务性能上不去(或偶尔卡顿)。所以一句话,Go 本身指针等还有性能会受到 GC 的影响,导致服务性能总是上不去。
-#### 为什么不使用其他开源的内存池? +### 为什么不使用其他开源的内存池? -1. 除Go本身的内存模块,调研了解现有大部分的第三方 对象池/内存池/字节池 等需要某块自主内存操作的场景中基本是Map/sync.Pool/Bytes[] 等方式。 +1. 除 Go 本身的内存模块,调研了解现有大部分的第三方 对象池/内存池/字节池 等需要某块自主内存操作的场景中基本是 Map/sync.Pool/Bytes[] 等方式。 -2. Map数据结构适合保存各类型数据,但GC概率大; sync.Pool 这类保存复用临时对象,也可以各种数据机构,可适当减少GC(无法避免GC); Bytes[] 方式来保存字节数据,并且只能保存字节数据,通过某些处理,尽量逃避GC扫描;(对比参考 [Go语言基于channel实现的并发安全的字节池](https://zhuanlan.zhihu.com/p/265790840) ) +2. Map 数据结构适合保存各类型数据,但 GC 概率大; sync.Pool 这类保存复用临时对象,也可以各种数据机构,可适当减少 GC(无法避免 GC); Bytes[] 方式来保存字节数据,并且只能保存字节数据,通过某些处理,尽量逃避 GC 扫描;(对比参考 [Go 语言基于 channel 实现的并发安全的字节池](https://zhuanlan.zhihu.com/p/265790840) ) -3. 现有开源库包括:依赖于 sync.Pool 的比如字节的mcache [gopkg/mcache.go](https://github.com/bytedance/gopkg/blob/main/lang/mcache/mcache.go) ;采用Bytes[]方式的比如MinIO 的 [bpool minio/bpool.go](https://github.com/minio/minio/blob/master/internal/bpool/bpool.go) ,都可以学习参考。 +3. 现有开源库包括:依赖于 sync.Pool 的比如字节的 mcache [gopkg/mcache.go](https://github.com/bytedance/gopkg/blob/main/lang/mcache/mcache.go);采用 Bytes[] 方式的比如 MinIO 的的 [bpool minio/bpool.go](https://github.com/minio/minio/blob/master/internal/bpool/bpool.go) ,都可以学习参考。 -4. 结论:XMM与他们实现机制完全不同,XMM更靠近Go内置内存分配机制原理 +4. 结论:XMM 与他们实现机制完全不同,XMM 更靠近 Go 内置内存分配机制原理
-#### XMM的最终设计结论是什么? +### XMM 的最终设计结论是什么? -为了完全实现最终为了逃逸掉Golang的Gc机制,以及拥有完全自主可控的内存管理分配操作,在面对成千上万的小对象场景中,不会因为Go本身GC机制带来任何的抖动,所以自主从零开始实现了XMM模块,达到在Go程序中调用XMM模块可以达到完美的自主内存 申请/释放/管理 的功能,并可以完美逃逸掉Go的GC机制。 +为了完全实现最终为了逃逸掉 Golang 的 GC 机制,以及拥有完全自主可控的内存管理分配操作,在面对成千上万的小对象场景中,不会因为 Go 本身 GC 机制带来任何的抖动,所以自主从零开始实现了 XMM 模块,达到在 Go 程序中调用 XMM 模块可以达到完美的自主内存 申请/释放/管理 的功能,并可以完美逃逸掉 Go 的 GC 机制。

-#### XMM设计的目标是什么? -为了保证高性能,XMM设计之初,就定下了三个核心目标: +### XMM 设计的目标是什么? +为了保证高性能,XMM 设计之初,就定下了三个核心目标: -1. 单机(6核心KVM或物理机)内存分配性能达到 350w+ alloc/s;(每秒内存分配速度); +1. 单机(6 核心 KVM 或物理机)内存分配性能达到 350w+ alloc/s;(每秒内存分配速度); -2. 可以支持调用用户手工强制Free某个申请内存块,也可以支持XMM自身自动Gc某些未手工Free的内存库;(自主实现Gc功能) +2. 可以支持调用用户手工强制Free某个申请内存块,也可以支持XMM自身自动GC某些未手工Free的内存库;(自主实现GC功能) 3. 不会内存泄露,并且内存管理不是粗糙的,而颗粒度细致的,完全尽量可媲美行业主流的内存管理分配器。 @@ -70,34 +84,35 @@ Golang本身为了性能和内存可控,整个内存管理是完全封闭不

-## XMM快速使用入门 +## XMM 快速使用入门 -#### ☆ [XMM使用案例](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-Usage.md) ☆ +### ☆ [XMM 使用案例](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-Usage.md) ☆
-说明:XMM测试程序快速预览下载使用 -1. [XMM使用-入门](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test00.go) -2. [XMM使用-结构体](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test01.go) -3. [XMM使用-链表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test02.go) -4. [XMM使用-哈希表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test03.go) +说明:XMM 测试程序快速预览下载使用 + +1. [XMM 使用 - 入门](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test00.go) +2. [XMM 使用 - 结构体](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test01.go) +3. [XMM 使用 - 链表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test02.go) +4. [XMM 使用 - 哈希表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test03.go)

-## XMM实现原理介绍 +## XMM 实现原理介绍 -1. [XMM的核心设计与实现流程](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-DesignImplementation.md) -1. [XMM设计实现技术调研参考](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-InvestigateResearch.md) +1. [XMM 的核心设计与实现流程](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-DesignImplementation.md) +1. [XMM 设计实现技术调研参考](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-InvestigateResearch.md)

-### XMM技术交流 +### XMM 技术交流 -XMM 目前是0.1版本,总体性能比较好,目前也在另外一个自研的XMap模块中使用,当然也少不了一些问题和bug,欢迎大家一起共创,或者直接提交PR等等。 +XMM 目前是 0.1 版本,总体性能比较好,目前也在另外一个自研的 XMap 模块中使用,当然也少不了一些问题和 bug,欢迎大家一起共创,或者直接提交 PR 等等。 -欢迎加入XMM技术交流微信群,要加群,可以先添加如下微信让对方拉入群: +欢迎加入 XMM 技术交流微信群,要加群,可以先添加如下微信让对方拉入群: @@ -111,5 +126,3 @@ XMM 目前是0.1版本,总体性能比较好,目前也在另外一个自研

- - diff --git a/docs/README.md b/docs/README.md index ae24f92..cc98572 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,25 +1,25 @@ ## XMM使用介绍 -#### - [XMM使用全介绍](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-Usage.md) +### - [XMM 使用全介绍](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-Usage.md)
-XMM测试程序快速预览下载使用: +XMM 测试程序快速预览下载使用:
-1. [XMM使用-入门](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test00.go) -2. [XMM使用-结构体](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test01.go) -3. [XMM使用-链表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test02.go) -4. [XMM使用-哈希表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test03.go) +1. [XMM 使用 - 入门](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test00.go) +2. [XMM 使用 - 结构体](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test01.go) +3. [XMM 使用 - 链表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test02.go) +4. [XMM 使用 - 哈希表](https://github.com/heiyeluren/XMM/blob/main/example/xmm-test03.go)

-## XMM实现原理介绍 +## XMM 实现原理介绍 -#### 1. [XMM的核心设计与实现流程](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-DesignImplementation.md) -#### 2. [XMM设计实现技术调研参考](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-InvestigateResearch.md) +### 1. [XMM 的核心设计与实现流程](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-DesignImplementation.md) +### 2. [XMM 设计实现技术调研参考](https://github.com/heiyeluren/XMM/blob/main/docs/XMM-InvestigateResearch.md)

diff --git a/docs/XMM-DesignImplementation.md b/docs/XMM-DesignImplementation.md index 3cbb842..262a3af 100644 --- a/docs/XMM-DesignImplementation.md +++ b/docs/XMM-DesignImplementation.md @@ -1,74 +1,81 @@ -# XMM的核心设计与实现流程 +# XMM 的核心设计与实现流程 +- [XMM 的核心设计与实现流程](#xmm-的核心设计与实现流程) + - [设计思考与要求](#设计思考与要求) + - [1、模块设计图](#1模块设计图) + - [2、数据结构](#2数据结构) + - [3、流程图](#3流程图) + - [3.1、启动分配 Start](#31启动分配-start) + - [3.2、申请内存 Alloc](#32申请内存-alloc) + - [3.3、申请 span 流程 Alloc span](#33申请-span-流程-alloc-span) -
- -### 设计思考与要求 +## 设计思考与要求 -XMM - X(eXtensible) Memory Manager(完全自主研发的第三方Go内存分配管理器) -XMM是一个在Go语言环境中完全自主实现的第三方内存管理库,不依赖于Go本身的任何内存管理能力,纯自主实现的Go内存管理库;能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建(链表/数组/树/hash等场景),能够良好完美的逃逸吊Go内置的GC机制,保证程序的超高性能,是构建高性能程序基础设施。 +XMM - X(eXtensible) Memory Manager(完全自主研发的第三方 Go 内存分配管理器) +XMM 是一个在 Go 语言环境中完全自主实现的第三方内存管理库,不依赖于 Go 本身的任何内存管理能力,纯自主实现的 Go 内存管理库;能够应对各种场景下大小内存的 分配/释放/管理 等工作,能够帮助适用于任何复杂数据结构的构建(链表/数组/树/hash 等场景),能够良好完美的逃逸掉 Go 内置的 GC 机制,保证程序的超高性能,是构建高性能程序基础设施。 -XMM主要特点: +XMM 主要特点: -1. XMM是完全自主研发的内存管理分配器(类似于 TCMalloc/Jemalloc/Ptmalloc 等),大部分场景可以不依赖于Go自带的内存管理器,目前在Golang方向无完全一样的同类产品。 -2. XMM设计中,能够逃逸掉Go内置的GC机制,所以程序不会因为GC导致应用程序性能卡顿,大幅提高程序运行性能。 -3. XMM分配性能绝佳,目前在比较一般硬件设备的Linux系统中,可以达到 350w+ alloc/s(单机每秒可以进行超过350万次内存分配操作),丝毫不会让你的程序卡顿。 -4. XMM内存库使用接口简单,兼容性强,能够兼容Go 1.8 以上版本,容易上手(推荐 go 1.12+版本更好) +1. XMM 是完全自主研发的内存管理分配器(类似于 TCMalloc/Jemalloc/Ptmalloc 等),大部分场景可以不依赖于 Go 自带的内存管理器,目前在 Golang 方向无完全一样的同类产品。 +2. XMM 设计中,能够逃逸掉 Go 内置的 GC 机制,所以程序不会因为 GC 导致应用程序性能卡顿,大幅提高程序运行性能。 +3. XMM 分配性能绝佳,目前在比较一般硬件设备的 Linux 系统中,可以达到 350w+ alloc/s(单机每秒可以进行超过 350 万次内存分配操作),丝毫不会让你的程序卡顿。 +4. XMM 内存库使用接口简单,兼容性强,能够兼容 Go 1.8 以上版本,容易上手(推荐 go 1.12+ 版本更好)
-为了达成以上的目标,进行了很多内存分配器的调研学习,通过golang malloc / tcmalloc 的学习,发现golang有高性能对象分配方式,但是需要对大对象GC买单:超大对象的GC会带来长时间的STP。面对我们大数据量的LocalCache显然不是那么友好,不能满足我们需求,所以,我们需要设计一个不参与gc的高性能内存分配。 +为了达成以上的目标,进行了很多内存分配器的调研学习,通过 Golang malloc/tcmalloc 的学习,发现 Golang 有高性能对象分配方式,但是需要对大对象 GC 买单:超大对象的 GC 会带来长时间的 STP。面对我们大数据量的 LocalCache 显然不是那么友好,不能满足我们需求,所以,我们需要设计一个不参与 GC 的高性能内存分配器。 (更多实现细节建议阅读源码)

-### 1、模块设计图 +## 1、模块设计图 + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/di01.png)
-### 2、数据结构 +## 2、数据结构 ```go -//核心堆结构 +// 核心堆结构 type xHeap struct { lock sync.mutex - + freeChunks *FreeChunkTree // 红黑树 rawMemorys rawMemory - + addrMap []*[]*rawMemory //addr -> page -> rawMemory 关系 - allchunk []*chunk + allchunk []*chunk } ​ -​//Span池 +​// Span 池 type spanPool struct{ spans [classSize]*span heap *xHeap } ​ -//写无锁atomic、扩容必须得全局锁 +// 写无锁 atomic、扩容必须得全局锁 type span struct{ lock sync.mutex - - classIndex uint // class的索引 - classSize uint // classSpan的长度 - - startAddr uintptr - npages uintptr + + classIndex uint // class 的索引 + classSize uint // classSpan 的长度 + + startAddr uintptr + npages uintptr freeIndex uintptr fact float32 // 扩容负载因子 } ​ -//连续page的管理 +// 连续 page 的管理 type chunk struct { - startAddr uintptr - npages uintptr + startAddr uintptr + npages uintptr } ​ -//用来管理mmap申请的内存,用于实际存放地址的元数据 +// 用来管理 mmap 申请的内存,用于实际存放地址的元数据 type rawMemory struct { addr uintptr data []byte @@ -82,23 +89,24 @@ type rawMemory struct {

-### 3、流程图 +## 3、流程图
-#### 3.1、启动分配 Start +### 3.1、启动分配 Start + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/di02.png)
-#### 3.2、申请内存 Alloc +### 3.2、申请内存 Alloc + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/di03.png)
-#### 3.3、申请span流程 Alloc span +### 3.3、申请 span 流程 Alloc span + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/di04.png)
- - diff --git a/docs/XMM-InvestigateResearch.md b/docs/XMM-InvestigateResearch.md index 47fc1f5..9122c48 100644 --- a/docs/XMM-InvestigateResearch.md +++ b/docs/XMM-InvestigateResearch.md @@ -1,67 +1,77 @@ -# XMM参考调研 - Tcmalloc&Go内存管理调研 +# XMM 参考调研 - TCMalloc&Go 内存管理调研 -
+- [XMM 参考调研 - TCMalloc&Go 内存管理调研](#xmm-参考调研---tcmallocgo-内存管理调研) + - [1、调研背景](#1调研背景) + - [2、TcMalloc 工作机制](#2tcmalloc-工作机制) + - [数据模型](#数据模型) + - [3、Go 内存分配机制](#3go-内存分配机制) + - [3.1、数据模型](#31数据模型) + - [3.2、内存初始化](#32内存初始化) + - [3.2、对象申请内存](#32对象申请内存) + - [相关参考文档](#相关参考文档) -### 1、调研背景 +## 1、调研背景 -为了解决golang的大内存GC问题,需要深入了解Golang的内存分配原理,Golang的内存分配器思想来源于tcmalloc,他继承了TcMalloc的高性能、高内存利用率等优点。实际上与tcmalloc有区别的,同时融入了自己的定制化内容。现在我们先了解下TcMalloc的实现原理。 +为了解决 Golang 的大内存 GC 问题,需要深入了解 Golang 的内存分配原理,Golang 的内存分配器思想来源于 TCMalloc,他继承了 TCMalloc 的高性能、高内存利用率等优点。实际上与 TCMalloc 有区别的,同时融入了自己的定制化内容。现在我们先了解下 TCMalloc 的实现原理。 -说明:TcMalloc - Multi-threaded memory allocate(Goolge开发的内存分配器) +说明:TcMalloc - Multi-threaded memory allocate(Goolge 开发的内存分配器)[github.com/google/tcmalloc](https://github.com/google/tcmalloc)
-### 2、TcMalloc 工作机制 +## 2、TcMalloc 工作机制
-在多线程环境下,TCMalloc可以极大减少锁资源的争夺。针对small object,TCMalloc几乎就是lock free的。针对large object,TCMalloc采用高效的细粒度的自旋锁。同时内存也做了更好管理更加精细化,较少了内存空洞。 +在多线程环境下,TCMalloc 可以极大减少锁资源的争夺。针对 small object,TCMalloc 几乎就是 lock free 的。针对 large object,TCMalloc 采用高效的细粒度的自旋锁。同时内存也做了更好管理更加精细化,较少了内存空洞。
-##### 数据模型 -- Page:page是一个以4KB对齐的内存区域。 -- Span:用来管理了连续的page,将连续的page划分到同一个span中。 -- ThreadCache:线程私有的内存,小于32k的对象在该区域分配。 -- ClassSpan:根据class等级,从CentralHeap申请内存,并分级。交给该线程私有内存管理。 +### 数据模型 + +- Page:page 是一个以 4KB 对齐的内存区域。 +- Span:用来管理了连续的 page,将连续的 page 划分到同一个 span 中。 +- ThreadCache:线程私有的内存,小于 32k 的对象在该区域分配。 +- ClassSpan:根据 class 等级,从 CentralHeap 申请内存,并分级。交给该线程私有内存管理。 - CentralHeap:堆空间。 -- 空闲span列表: 记录空闲Span的结构,用于申请内存和释放内存使用。 -- SpanMap:维护了地址到span的映射关系。通过地址查询span地址,用于span合并。 +- 空闲 span 列表: 记录空闲 Span 的结构,用于申请内存和释放内存使用。 +- SpanMap:维护了地址到 span 的映射关系。通过地址查询 span 地址,用于 span 合并。

-### 3、Go内存分配机制 +## 3、Go 内存分配机制 ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/ir02.png)
-#### 3.1、数据模型 +### 3.1、数据模型 + - heapArena: 保留整个虚拟地址空间。 -- arena:用来分配实际的系统内存arenas(调用系统函数mmap申请) -- mspan:是 mheap 上管理的一连串的页,作为span的管理者。 -- mheap:分配的堆,在页大小为 8KB 的粒度上进行管理,并分配为不同的span。 -- mcentral:通过不同等级mcentral搜集了给定大小等级的所有 span,作为mcache的预划分。 -- mcache:为 per-P 的缓存,协程运行时私有local heap,内部有不同class的span,作为不同长度的对象保存。 +- arena:用来分配实际的系统内存 arenas(调用系统函数 mmap 申请) +- mspan:是 mheap 上管理的一连串的页,作为 span 的管理者。 +- mheap:分配的堆,在页大小为 8KB 的粒度上进行管理,并分配为不同的 span。 +- mcentral:通过不同等级 mcentral 搜集了给定大小等级的所有 span,作为 mcache 的预划分。 +- mcache:为 per-P 的缓存,协程运行时私有 local heap,内部有不同 class 的 span,作为不同长度的对象保存。
-#### 3.2、内存初始化 +### 3.2、内存初始化 + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/ir03.png)
-#### 3.2、对象申请内存 +### 3.2、对象申请内存 + ![这是图片](https://raw.githubusercontent.com/heiyeluren/XMM/main/docs/img/ir04.png)
-#### 相关参考文档: - -1. [详解Go语言的内存模型及堆的分配管理](https://zhuanlan.zhihu.com/p/76802887) -2. [Go语言内存管理](https://www.jianshu.com/p/7405b4e11ee2) +### 相关参考文档 -
+1. [详解 Go 语言的内存模型及堆的分配管理](https://zhuanlan.zhihu.com/p/76802887) +2. [Go 语言内存管理](https://www.jianshu.com/p/7405b4e11ee2) diff --git a/docs/XMM-Usage.md b/docs/XMM-Usage.md index 9f0ed14..789c0d6 100644 --- a/docs/XMM-Usage.md +++ b/docs/XMM-Usage.md @@ -1,13 +1,20 @@ -## XMM如何使用案例说明 - +## XMM 如何使用案例说明 + +- [XMM 如何使用案例说明](#xmm-如何使用案例说明) + - [示例一:XMM 快速使用入门](#示例一xmm-快速使用入门) + - [示例二:如何在结构体中使用 XMM](#示例二如何在结构体中使用-xmm) + - [示例三:使用 XMM 构建一个链表](#示例三使用-xmm-构建一个链表) + - [示例四:使用 XMM 构建一个哈希表](#示例四使用-xmm-构建一个哈希表) +- [XMM问题反馈](#xmm问题反馈)

-### XMM使用示例一: -XMM的使用非常简单方便,我们直接通过代码来看。 +### 示例一:XMM 快速使用入门 + +XMM 的使用非常简单方便,我们直接通过代码来看。 -示例一:看一个快速入门的例子,简单常用变量采用XMM进行存储 +示例一:看一个快速入门的例子,简单常用变量采用 XMM 进行存储 ```go /* @@ -76,9 +83,9 @@ func main() {
-#### 示例二:如何在结构体中使用XMM +### 示例二:如何在结构体中使用 XMM -说明:稍微复杂一点的应用,如何在结构体中使用XMM,进行申请和释放内存操作: +说明:稍微复杂一点的应用,如何在结构体中使用 XMM,进行申请和释放内存操作: ```go @@ -162,9 +169,9 @@ func main() {

-### 示例三:使用XMM构建一个链表 +### 示例三:使用 XMM 构建一个链表 -说明:通过XMM构建一些复杂的数据结构应用,构建一个单链表的结构使用 +说明:通过 XMM 构建一些复杂的数据结构应用,构建一个单链表的结构使用
@@ -316,9 +323,9 @@ func main() {

-### 示例四:使用XMM构建一个哈希表 +### 示例四:使用 XMM 构建一个哈希表 -说明:通过XMM构建一些复杂的数据结构应用,构建一个哈希表的数据结构使用(代码比较长,可以跳过阅读) +说明:通过 XMM 构建一些复杂的数据结构应用,构建一个哈希表的数据结构使用(代码比较长,可以跳过阅读) ```go @@ -420,7 +427,7 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { pEntity := (*XEntity)(p) pEntity.Key = pKey pEntity.Value = pVal - + //--------------- // 挂接到Bucket //---------------