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

malloc内存池

  • 内存
  • 2024-08-13 02:25:22
  • 3832

一、OceanBase-4.0社区源码-内存篇以及C++知识扩展(OB代码-》/lib/alloc相关)-上篇OceanBase-4.0社区源代码的内存章节对内存池及其C++实现进行了深入讨论,特别关注相关的`/lib/alloc`部分。内存池的核心是减少内存碎片,通过提前申请大内存块并划分使用,可以减少频繁申请小块内存带来的内存管理问题。
内存池实现主要包括提前申请大内存,分成小块供程序使用,使用后并不立即释放,而是回收。C++中的函数“malloc()”、“calloc()”和“realloc()”各有特点:“malloc()”用于动态内存分配,“calloc()”分配内存并初始化为零,`realloc()`用于调整分配的内存大小。使用这些函数时要注意内存泄漏,尤其是`realloc()`虽然可以减少内存申请次数,但也可能带来数据移动和潜在风险。
OceanBase源码分析重点关注`ob_`,该文件负责内存分配和释放,通过`ObTenantCtxAllocatorGuard`和`ABlock`管理内存。`abit_`和`abit_set.h`用于位图管理和标记分配的内存,而`alloc_`和`alloc_assist.h`提供用于内存分配和管理的辅助函数。`alloc_failed_reason`定义了内存分配失败的原因,例如`VmRSS`、`VmHWM`等进程内存使用情况指标。
源代码还包括一种使用箭头运算符和线程本地存储(RLOCAL)概念来访问结构成员的有效方法。`alloc_`和`alloc_func.h`进一步实现了内存分配相关的函数,展示了OceanBase中回调函数的应用以及extern"C"、nodiscard等C++特性在内存管理中的应用。
总的来说,第一部分为理解OceanBase的内存管理机制提供了基础,下一部分将深入分析更多细节和调用逻辑,以及与C++技术的结合点。通过阅读,您将对OceanBase的内存池实现和内存管理有更深入的了解。


二、内存池操作中分配内存块的接口函数是什么?

在内存池操作中,分配内存块的接口函数通常被称为“内存池分配函数”。不同的存储池实现可能有不同的函数名称,但通常具有相似的功能。

以下是一些常见的内存池分配函数:

malloc:C标准库提供的函数,用于在堆上分配特定大小的内存块。例如:void*malloc(size_tsize);

calloc:C标准库提供的函数,用于在堆上分配特定数量和大小的内存块,并将其初始化为零。示例:void*calloc(size_tnum,size_tsize);

new:C++关键字,用于在堆上分配指定类型的对象。示例:int*ptr=newint;

特定于存储池的分配函数:某些存储池实现提供自定义分配函数,用于在预分配的内存池中分配内存块。这些函数的名称和参数可能因实现而异。例如:void*pool_alloc(MemoryPool*pool,size_tsize);

需要注意的是,不同的内存池实现可能有不同的接口函数。使用哪个能取决于您选择的存储池库或自行实现的存储池。在实现过程中,建议参考所使用的​​存储池库的文档或相应的代码文档,了解接口函数的详细信息。


三、malloc()到底如何申请内存空间malloc()从哪里获取内存空间?
答案是从堆中获取空间。也就是说,函数返回的指针指向堆中的一块内存。
操作系统中有一个链表,记录着空闲内存地址。当操作系统收到程序的申请时,会遍历链表,然后寻找第一个空间大于请求空间的堆节点,然后从空闲节点链表中删除该节点并替换该节点。点空间分配给程序。
malloc函数的本质是它有一个所谓的空闲列表(FreeList),将可用的内存块连接成一个长列表。当malloc函数被调用时,它会沿着连接表查找足够大的内存块来满足用户的请求(根据不同的算法而定)(第一个找到的不小于请求大小的内存块分配给请求者,这将所请求的空闲内存大小分配给请求者,或者分配最大的空闲块内存块),然后将内存块分为两块(一块的大小等于所请求的大小)。由用户指定,另一个块的大小是剩余的块)。字节)。接下来,将分配给用户的内存传递给用户,并将剩余块(如果有)返回到连接表。当free函数被调用时,它被返回给用户。释放的内存块连接到空闲链上。最终,空闲链会被切割成很多小的内存碎片。如果用户此时申请较大的内存碎片,则空闲链上可能没有可以满足用户要求的碎片。因此,malloc函数请求延迟,开始翻找空闲链上的内存碎片,将它们组织起来,将相邻的小空闲块合并成更大的内存块。如果无法获得符合要求的内存块,malloc函数将返回NULL指针,因此在调用malloc动态申请内存块时,必须对返回值进行判断。
这里还需要注意的是,new和malloc需要满足众申请内存空间的要求。由泛型提供,分配内存旨在分配算法和搜索。另外,必须避免内存碎片,因此其效率比较低。因此,有时候程序员会自己重写new和delete,或者创建内存池来管理内存,改进程序。运营效率。