首页 > 系统相关 >Linux 动态内存分配

Linux 动态内存分配

时间:2023-06-21 12:57:37浏览次数:47  
标签:malloc 动态内存 header 空闲 分配器 Linux 分配 block

动态内存分配器

进程中名为 heap 的 VM area 就是由动态内存分配器(dynamic memory allocator)来维护的。Heap 会向高地址(向上)增长。对每个进程,内核维护着一个名为 brk 的变量,该变量指向 Heap 的顶部,如下图所示:

bjmDgoT7GqH14C8

Allocator 将 Heap 视为一组不同大小的 block 组成的集合来维护。这里 block 和 chunk 的概念是等价的,该 block 要么是已分配的(allocated),要么是空闲的(free)。

Each block is a contiguous chunk of virtual memory that is either allocated or free.

Allocator 可以分为显式分配器(explicit allocator)和隐式分配器(implicit allocator)。

  • 显示分配器要求应用显示地释放任何已分配的块,分配也需要手动分配。例如 C 中的 mallocfree,C++ 中的 newdelete
  • 隐式分配器又被称为垃圾收集(garbage collection),例如 Java、C#。

mallocfree

$32$ 位系统中,malloc 返回的地址总是 $8$ 的倍数,即 malloc 返回的地址的最低三位总是 $0$,亦即 malloc 分配的 block 至少占据 $8$ 的倍数个 byte;而 $64$ 位系统中,malloc 返回的地址总是 $16$ 的倍数。

即 $32$ 系统中,malloc 分配内存是 $8$ 字节对齐的;$64$ 位系统中,malloc 分配内存是 $16$ 字节对齐的。

Allocator 的设计要求和目标

显式分配器必须在一些相当严格的约束条件下也能正常工作:

  • 处理任意请求序列:不能假设所有分配都有相匹配的释放请求等;
  • 立即响应请求:不允许分配器为了提高性能重新排列或者缓冲请求;
  • 只使用 Heap
  • 对齐(aligning) block:$32$ 位系统 $8$ 字节对齐,$64$ 位系统 $16$ 字节对齐;
  • 不允许修改已分配的 block:一旦 block 被分配就不允许修改或者移动,除非被释放(free);

同时我们希望设计的分配器能最大化内存利用率最大化吞吐率(即每秒能完成的分配或者释放请求数量)。

碎片(Fragmentation)

碎片分为内部碎片(internal fragmentation)和外部碎片(external fragmentation)。

内部碎片即要分配的 $size$ 只占分配的 $block size$ 的一部分的情况,例如分配一个 $2$ 字节的空间,由于要求至少 $8$ 字节对齐,那么必然有一部分用不到的空间为了满足对齐要求也被分配了出来。

外部碎片即空闲的空间总和大于要分配的 $size$,但是没有一个单独的 $block$ 的 $size$ 大到可以处理该分配请求。

jpLhuXNnIB27kPO

分配器实现

分配器实现过程中,我们需要考虑以下问题:

  • 空闲 block 组织:如何记录空闲 block?
  • 放置:如何选择一个合适的空闲 block来放置一个新分配的 block?
  • 分割:将一个新分配的块放置到某个空闲 block 之后,如何处理空闲 block 的剩余部分?
  • 合并:如何处理一个刚刚释放的 block(例如前或者后也有 free 的 block 呢)?

隐式空闲链表

一般来说,allocator 需要一些数据结构,从而区分 block 的边界并区分 allocated block 和 free block。大多数的 allocator 将信息嵌入这个块本身,就像 elf 文件有一个 elf header 一样,block 中也会有一个 header,存储了该 block 是否空闲,占据的空间 size 等信息。

GC2LdqlwUK4k9WR

假设 malloc 返回的指针是 p,由于 header 占据了 $32$ 个字节,header 本身是 uint32_t 类型的。那么 block 的起始地址 start

uint64_t start = (uint64_t)p - 4; // block 的起始地址
uint32_t header_val = *((uint32_t *)start); // header 的值
int allocated = header_val & 0x1; // 为 1 表示已分配,为 0 表示块仍然是空闲的
int size = header_val & 0xfffffffe; // 即将 header_val 的最后一位置 0

这种结构被称为隐式空闲链表,我们可以利用 block 的 header_val 中的 size 找到下一个块:next = (uint64_t)start + size;

隐式空闲链表的主要优点是简单,缺点则是:任何操作都可能需要遍历 heap 中的所有 block,时间复杂度是 $O(n)$ 的,此外还有个缺点是可能造成内部碎片

标签:malloc,动态内存,header,空闲,分配器,Linux,分配,block
From: https://www.cnblogs.com/zwyyy456/p/17495973.html

相关文章

  • Linux:一个人加上一百万人的智慧
    如果说KenThompson是Unix的创造者,那么LinusTorvalds就是Linux操作系统的发明人,当时他还是芬兰赫尔辛基大学的一名学生。1991年8月25日他发出了那篇现在广为人知的新闻组主题文章,这篇以“嗨,大家好……我正在编写一个(免费)的操作系统”开头的文章对他的命运产生了深远影响。Thompson......
  • 深度解读 Linux 内核级通用内存池 —— kmalloc 体系
    本文是笔者slab系列的最后一篇文章,为了方便大家快速检索,先将相关的文章列举出来:《细节拉满,80张图带你一步一步推演slab内存池的设计与实现》《从内核源码看slab内存池的创建初始化流程》《深入理解slabcache内存分配全链路实现》《深度解析slab内存池回......
  • Linux命令行设置时区
    引言在linux安装好了过后,如果时区不正确,需要手动地对它设置我们需要的时区设置控制台输入tzselect,回车tzselect2.然后选择5“Asia”亚州,回车3.然后选择国籍9“China”中国,回车4.选择具体的时区,输入1,选择“BenjingTime”,回车5.确认所选择的内容,正确无误后输......
  • 来自 VMWare 的开源 Linux 容器系统: Photon OS 5.0 发布
    导读PhotonOS 是一个开源 Linux 容器主机,针对云原生应用程序、云平台和VMware基础架构进行了优化。 PhotonOS 为高效运行容器提供了安全的运行时环境。PhotonOS 的一些主要亮点是:针对VMwarehypervisor进行了优化:当PhotonOS在VMwareESXi上运行时,Lin......
  • 关于在Redhat-7-linux-系统-Apache-2.4.6-版本上部署多个版本的yum仓库-的配置文件写
    背景:云上有一台内部yum服务器,操作系统及版本信息为:RedHatEnterpriseLinuxServerrelease7.9(Maipo)上面每天会同aws仓库官网同步repo,版本也自然是 RedHatEnterpriseLinuxServerrelease7现在需要临时增加Redhat8.的仓库,(默认Redhat8也是有内部repo仓库的,只是在......
  • 目前最全面深入的Linux设备驱动程序著作
    《精通Linux驱动程序开发(英文版)》在Linux内核源代码树提供的各个子系统中,drivers/目录是其中最大的一个分支,它比其他子系统大数倍。随着各种新技术的广泛应用,内核中新的设备驱动程序的开发工作正在稳步加速。最新的Linux内核支持多达70余种设备驱动程序的庞大家族。《精通Linux驱动......
  • 《Red Hat Linux命令速查》—— 带你玩转字符游戏
    命令行管理,一个玩转字符的战场!忽隐忽现的光标  神秘莫测的符号  闪转腾挪的玄机  直捣黄龙的快意能领略这一切的人,只有你——深谙命令行管理之道的系统管理员和软件开发人员!命令行之于优秀的系统管理员、软件开发人员,恰如武林高手必须修炼的内功心法,一旦掌握,不仅可以大大提高......
  • Linux中的基础知识
    【技术积累】Linux中的基础知识【一】Linux系统是什么Linux系统是一种开源操作系统,它极具可定制性和灵活性,因此受到了许多人的欢迎。Linux系统以简单,强大和兼容性而著称。它可用于各种设备,从个人计算机到超级计算机,从移动设备到智能家居。Linux系统遵循GNU公共许可证(GPL)下的自......
  • 《Linux命令详解手册》——Linux畅销书作家又一力作
     关注IT,更要关心IT人,让系统管理员以及程序员工作得更加轻松和快乐。鉴于此,图灵公司引进了国外知名出版社JohnWileyandSons出版的FedoraLinuxToolbox:1000+CommandsforFedora,CentOSandRedHatPowerUsers (中文名《 Linux命令详解手册》预计在9月份上市,敬请期待!内......
  • linux gpio dev,linux gpio子系统 devicetree中GPIO_ACTIVE_LOW
    一直没怎么理解GPIO_ACTIVE_LOW的作用对于以上的dts你应该再熟悉不过,当然这里不是教你如何使用dts,而是关注gpio和irq最后一个数字可以如何利用。例如rst-gpio的OF_GPIO_ACTIVE_LOW代表什么意思呢?可以理解为低有效。什么意思呢?举个例子,正常情况下,我们需要一个gpio口控制灯,我们认......