当前位置:首页 > 内存 > 正文

malloc分配的内存

  • 内存
  • 2024-08-27 04:37:04
  • 5842

一、Linux内存管理(三)--内存分配之malloc在本文中,我们将了解Linux中动态内存分配的核心机制,特别是malloc函数的工作原理。开源社区提供了丰富的内存分配器,其中glibc的ptmalloc2是一个基于dlmalloc的示例,并引入了多线程支持。malloc的源代码位于文件glibc-2.37\malloc\malloc.c中,它实际上指向别名__libc_malloc的内部实现。
动态内存分配主要通过两个系统调用来完成:mmap和brk。如果所需的内存大小超过预设阈值(默认128KB),则使用mmap分配,否则使用brk分配。该策略旨在平衡系统调用频率和内存分配效率。
为了提高效率,malloc实际上是利用了池化的思想来预先分配较大的内存块,以便后续的请求可以直接使用它们,从而避免频繁的系统调用。这个过程涉及到几个核心数据结构的使用,包括arena、malloc_state、heap_info、chunk等。
Arena用于表示连续的堆区域,分为mainarena和threadarena。mainarena作为全局变量存在于的数据段中。不需要维护多个堆,并且可以通过sbrk扩展堆段。当内存耗尽时,mainarena可以通过sbrk或mmap扩展堆段以遇到内存映射段。另一方面,如果线程数量超过arena数量,则线程数量将受到限制,arena将开始共享。
Heap_info用于存储堆元数据。当threadarena的堆空间耗尽时,一个新的堆被映射到threadarena。chunk是描述内存分配的基本单位,包括chunk大小、之前chunk的状态信息以及对齐要求。
就内存组织而言,有不同类型的块:已分配块、空闲块、顶部块和最后剩余块。Topchunk位于竞争环境的顶部,用于处理在任何存储库中都找不到足够的可用内存的情况。如果Topchunk大小不够,则通过系统调用对其进行分割或扩展。
Prechunk管理、brk和mmap将在后续文章中详细讨论。有关内存管理的更多信息,请参见《嵌入式Linux笔记》专栏。引用时请注明出处。


二、15+张图剖析内存分配之malloc详解在这篇文章中,我们将详细分析内存分配中的malloc函数。我不会详细介绍源代码,但会重点介绍它的实际工作原理。首先,了解malloc分配的内存结构很重要。
当malloc分配内存时,它会添加额外的标头和尾部。如,用户请求分配的0x100字节内存的浅绿色区域,并返回该区域的起始指针。填充区域周围有一个预先填充的间隙,用于区分用户可以使用的区域和不可使用的区域,并且可以在返回时检测您是否离开该区域。
内存管理涉及层次结构。在程序启动之前,系统使用__cdecl_heap_init分配堆空间,并构建一个包含16个HEADER节点的链表,每个HEADER节点管理1MB内存。每个节点结构都包含指向与未分配的“房屋地址”相对应的虚拟地址空间的pHeapData。
下一步是手动分区和管理内存页。的内存页根据需要被分成32K段,并挂载在链表中。分配和返回过程包括从链表中查找空间、打开新组、组合空闲内存以及记录使用情况。当一个group被完全回收后,并不是立即返回到系统,而是等到其他group一起回收,以提高效率。
上面的图和步骤让我们对malloc内存分配有一个直观的了解。要了解更多信息,请查看相关视频教程(例如我们的C++开发系列),并获取更多针对C/C++和Linux架构师的学习资源。