我期待着了解GNU/Linux系统中动态内存管理是如何在低级别工作的(也就是ptmalloc是如何工作的)。
当然,我已经阅读了代码,但我有很多疑问。I、 或多或少,了解数据结构,但我有很多信息泄露!
我的问题是,是否有人知道任何详细解释实现的资源。例如,我读过诸如"通过打破堆来理解堆"或"Malloc Mallefacarum"系列和post系列之类的论文。它们做得很好,但当然,它们更专注于开发,而不是解释许多实现细节。
如果你不知道任何资源,下面是我的一些问题。
-
竞技场到底是什么?在heap_info结构的变量ar_ptr的代码中,有一条注释说"arena for this heap",因此arena不能是堆(到处都说)。
-
为什么在heap_info结构中没有下一个指针,而有prev指针?是因为main_arena吗?什么是main_arena?
-
每个heap_info结构都可以有多个arena(指向不同的malloc_state构造)?
-
什么时候创建了新闻领域,什么代码处理它?我读到当请求存储数据的arena被锁定时(因为进程或进程线程正在使用它)会创建新的arena,我也读到每个进程线程都有不同的arena。这里重要的是,如果您知道哪些代码可以处理这些情况。
-
我也不明白为什么人们说所有的内存操作都是从最顶层或最底层产生的。你知道我在哪里可以找到这个代码吗?
顺便说一句,我不想深入讨论互斥的细节。
我正在审查glibc 2.12.1中ptmalloc的实现。我想做一些关于所有东西的整体结构的图表,所以我需要理解这些东西!
谢谢。
好的,我已经做了一些研究,其中许多问题我都有答案。
-
竞技场是存储一个进程的所有动态数据的存储区域。简而言之,竞技场是过去被称为堆的内存结构。考虑到现在(使用多线程的东西)您希望每个进程有一个以上的堆,您可以通过创建一个名为arena的东西来处理它,但这个arena只不过是一个堆。heap_info结构只管理流程的多个现有领域。
-
我不知道为什么只有prev指针。我所知道的是,通常情况下,所有的动态数据都存储在main_arena中,这是为该过程创建的竞技场。我不知道在什么情况下不使用main_arena,我知道的是,如果内存块中的size字段设置了NON_main_ARNA位,那么就不使用
main_arenaeap_for_prt()宏清除该内存块指针的20个低有效位来获得新的arena地址。总之,在正常情况下,将始终使用main_arena。 -
是的,正如我所说,每个heap_info结构都可以有多个竞技场。这是因为锁争用。如果你有足够的空闲时间,你可以在[1]中阅读这方面的内容。
-
我不记得这个了。但事实是,如果竞技场在使用中,被锁定,就会创建一个新的竞技场。搜索对类似于new_arena()或new_heap()的函数的任何调用。我记得函数名称与此类似。
-
我认为这只是意味着在一开始,堆的所有内存空间都是顶部块(或荒野块),所以当进程需要新的内存请求时,这个顶部块就会被分割和碎片化。所以这一切都是从最上面的大块开始的。
我不想浮夸,我认为三个月后,我的答案会更适合我的问题,所以我会把它作为正确的答案。另一方面,感谢所有其他的回答。他们真的很有帮助。
顺便说一句,我已经把所有这些研究都写在了一篇论文中,但鉴于它是西班牙语的,我认为它在这里没有用处,我也不知道它是否会被视为垃圾邮件。[2]
[1]http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.16.4439
[2] 这是你的论文:http://overflowedminds.net/papers/newlog/linux_heap_exploiting_revisited.pdf
堆基本上被划分为许多小区域,这些区域独立地满足一个或多个分配的对象。一个这样的区域可能被称为竞技场或区域。堆主要是满足对象需求的竞技场的集合,要求在单个操作中可以释放一个竞技场。为了实现这一点,一个完整的竞技场被分配为一个连续的内存地址范围。
竞技场或区域之间的区别是灰色的。我不确定Linux,但一个例子是Cavium网络公司的一个名为Octeon的真实世界多核网络处理器家族。它将分配的内存视为竞技场或区域,不同之处在于区域可以分配固定大小相等的对象,而竞技场可以有不同大小的对象。在竞技场的情况下,这自然会导致碎片化。但我不能确认Linux是否也是这样。
基于区域的内存管理