内存管理器剖析:ptmalloc,windows,macOS

本文介绍了Linux、Windows和MacOS三种操作系统中的内存管理器所使用的数据结构。通过理解这些数据结构,用户可以更好地利用CoreAnalyzer这样的工具来检查内存损坏并搜索对象引用。文章还提供了有关如何在不同操作系统中遍历内存堆的详细信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. Ptmalloc 

2. Windows内存管理器 

3. Mac OS内存管理器 

4.推荐阅读


 

核心分析器的优势在于它能够将堆内存解析为数百万个单独的内存块,这些内存块由堆内存管理器分配给应用程序。只有掌握了这些知识,Core Analyzer才能检查内存损坏并搜索对象引用。鼓励用户了解基本堆数据结构,以最大程度地利用该工具的好处,并在必要时开发自己的自定义内存管理器支持。

我将简要说明Linux / Windows / Mac OS系统运行时内存管理器使用的数据结构。它们是开源的或反向工程的。您可以在项目的源文件,Linux内核源代码或许多在线网站中找到更多详细信息。由于操作系统供应商可能会更改每个新版本的实现,因此此描述可能与您使用的描述不同。在下面的所有图中,阴影区域表示堆数据结构,空白区域表示用户空间。

 

1. Ptmalloc 


这是Linux上GNU C库使用的内存管理器。图书馆的glibc有一个全球性的“结构malloc_state ”对象,名为main_arena ,这是所有托管堆内存的根源。

Arena是存储区域的逻辑集合,用各种彩色轮廓表示。竞技场可以一次满足一个内存请求。如果同时存在多个请求,则ptmalloc将使用其他场所同时满足这些请求。如果没有可用的竞技场,则会创建新的竞技场。堆是由用户存储块组成的单个连续存储区。竞技场随时可能有一个或多个竞技场。

主竞技场和动态创建的竞技场之间的区别在于它们如何从内核获取内存。主区域调用sbrk(),通常在可执行文件的数据部分之后立即开始。另一方面,动态竞技场使用具有固定大小(例如64MB )的mmap(),并确保起始地址也按大小的倍数对齐。如果第一个堆用完了,则将对新的具有固定大小的堆进行mmap-ed,该堆将链接到动态竞技场的堆数据“ strcut malloc_state ”。

如果用户的请求超出了可以动态更改的阈值(例如128KB),则ptmalloc在释放时会调用mmap()来分配内存和munmap()。此类存储块不由任何堆数据链接。

堆上的每个内存块都由“ struct malloc_chunk ”边界标记管理。我们可以轻松地将堆作为链接列表遍历,每个标签作为到下一个内存块的偏移量。

    struct malloc_chunk {
        INTERNAL_SIZE_T prev_size;
        INTERNAL_SIZE_T大小;
        struct malloc_chunk * fd;
        struct malloc_chunk * bk;
    };

 根据某个块及其上一个和下一个块是空闲的还是正在使用的,该结构的某些数据字段未使用,可能是用户空间的一部分。阴影区域中的数据是堆数据,属于ptmalloc。如果被应用程序覆盖,则是典型的堆数据损坏。

 

2. Windows内存管理器 


为了遍历Windows上的内存堆,我们从全局对象peb (进程环境块)开始。它的数据成员“ ProcessHeaps ”指向“ struct _HEAP ”的指针数组,该数组以NULL指针终止。堆保留段列表。

段是一块连续的内存空间,由“ struct _HEAP_SEGMENT 描述。它具有指向该段中第一个和最后一个存储块的指针。该段中还有一些未提交的内存范围,必要时将使这些范围可用。每个内存块前面都有一个“ struct _HEAP_ENTRY ”,该信息由该块的用户空间大小,填充,状态,加密字节等信息组成。在调试模式下,在用户空间之前添加“ struct _CrtMemBlockHeader ”。

 

3. Mac OS内存管理器 


Mac OS上的内存管理器有两个全局变量位于堆数据结构的顶部:“ malloc_zones ”和“ malloc_num_zones ”。前者指向“ struct szone_t ”数组,而后者则指向该数组的大小。与glibc的Ptmalloc相比,zone等同于Mac OS上的竞技场,而region与堆相同。创建多个区域以同时服务多个线程。

像大多数内存管理器一样,根据内存请求的大小采用不同的算法。如果内存请求大小不大于31 * TINY_QUANTUM或496字节,则使用微小区域。如果大小等于或大于15KB,则使用大区域。否则,将选择小区域来满足请求。它们的堆数据结构如下所示。与Ptmalloc不同,每个内存块都没有附加标签。相反,每个区域都有一个位图,用于标记该区域中相应块的状态。

http://core-analyzer.sourceforge.net/index_files/Page335.html

 

4.推荐阅读


jemalloc简介

图解tcmalloc内存分配器

TCMalloc:线程缓存Malloc以及tcmalloc与ptmalloc性能对比

TCMalloc内存分配器如何减少内存碎片?

ptmalloc、tcmalloc与jemalloc内存分配器对比分析

使用jemalloc在Go中进行手动内存管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值