linux内存管理机制--学习整理汇总(2)

本文介绍了Linux内存管理中的内存碎片问题及其避免策略,详细阐述了slab算法的工作原理,用于减少内部碎片。同时,探讨了内核态内存池的概念和API,以及DMA内存在硬件交互中的作用。还涵盖了用户态内存分配函数,如malloc、calloc和realloc等。通过对内存管理的理解,有助于优化系统性能和资源利用率。
摘要由CSDN通过智能技术生成

Linux 内存分配算法

内存管理算法——对讨厌自己管理内存的人来说是天赐的礼物

1、内存碎片

1) 基本原理

产生原因:内存分配较小,并且分配的这些小的内存生存周期又较长,反复申请后将产生内存碎片的出现

优点:提高分配速度,便于内存管理,防止内存泄露

缺点:大量的内存碎片会使系统缓慢,内存使用率低,浪费大

2) 如何避免内存碎片

少用动态内存分配的函数(尽量使用栈空间)

分配内存和释放的内存尽量在同一个函数

尽量一次性申请较大的内存,而不要反复申请小内存

尽可能申请大块的 2 的指数幂大小的内存空间

外部碎片避免——伙伴系统算法

内部碎片避免——slab 算法

自己进行内存管理工作,设计内存池

slab 算法——基本原理

1) 基本概念

Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。

它的基本思想是将内核中经常使用的对象放到高速缓存中,并且由系统保持为初始的可利用状态。比如进程描述符,内核中会频繁对此数据进行申请和释放

2) 内部碎片

已经被分配出去的的内存空间大于请求所需的内存空间3) 基本目标

减少伙伴算法在分配小块连续内存时所产生的内部碎片

将频繁使用的对象缓存起来,减少分配、初始化和释放对象的时间开销

通过着色技术调整对象以更好的使用硬件高速缓存

9、内核态内存池

1) 基本原理

先申请分配一定数量的、大小相等(一般情况下) 的内存块留作备用

当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存

这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升

2) 内核 API

mempool_create 创建内存池对象

mempool_alloc 分配函数获得该对象

mempool_free 释放一个对象

mempool_destroy 销毁内存池

DMA 内存

1) 什么是 DMA

直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的 I/O 数据,而不需要系统处理器的参与

2) DMA 控制器的功能

能向 CPU 发出系统保持(HOLD)信号,提出总线接管请求

当 CPU 发出允许接管信号后,负责对总线的控制,进入 DMA 方式

能对存储器寻址及能修改地址指针,实现对内存的读写操作

能决定本次 DMA 传送的字节数,判断 DMA 传送是否结束

发出 DMA 结束信号,使 CPU 恢复正常工作状态

3) DMA 信号

DREQ:DMA 请求信号。是外设向 DMA 控制器提出要求,DMA 操作的申请信号

DACK:DMA 响应信号。是 DMA 控制器向提出 DMA 请求的外设表示已收到请求和正进行处理的信号

HRQ:DMA 控制器向 CPU 发出的信号,要求接管总线的请求信号。

HLDA:CPU 向 DMA 控制器发出的信号,允许接管总线的应答信号:

1、内存的使用场景

page 管理

slab(kmalloc、内存池)

用户态内存使用(malloc、relloc 文件映射、共享内存)

程序的内存 map(栈、堆、code、data)

内核和用户态的数据传递(copy_from_user、copy_to_user)

内存映射(硬件寄存器、保留内存)

DMA 内存

2、用户态内存分配函数

alloca 是向申请内存,因此无需释放

malloc 所分配的内存空间未被初始化,使用 malloc() 函数的程序开始时(内存空间还没有被重新分配) 能正常运行,但经过一段时间后(内存空间已被重新分配) 可能会出现问题

calloc 会将所分配的内存空间中的每一位都初始化为零

realloc 扩展现有内存空间大小

 

a) 如果当前连续内存块足够 realloc 的话,只是将 p 所指向的空间扩大,并返回 p 的指针地址。这个时候 q 和 p 指向的地址是一样的

b) 如果当前连续内存块不够长度,再找一个足够长的地方,分配一块新的内存,q,并将 p 指向的内容 copy 到 q,返回 q。并将 p 所指向的内存空间删除

mmap 将一个文件或者其它对象映射进内存,多进程可访问

3、内核态内存分配函数函数分配原理最大内存其他_get_free_pages直接对页框进行操作4MB适用于分配较大量的连续物理内存kmem_cache_alloc基于 slab 机制实现128KB适合需要频繁申请释放相同大小内存块时使用kmalloc基于 kmem_cache_alloc 实现128KB最常见的分配方式,需要小于页框大小的内存时可以使用vmalloc建立非连续物理内存到虚拟地址的映射物理不连续,适合需要大内存,但是对地址连续性没有要求的场合dma_alloc_coherent基于_alloc_pages 实现4MB适用于 DMA 操作ioremap实现已知物理地址到虚拟地址的映射适用于物理地址已知的场合,如设备驱动alloc_bootmem在启动 kernel 时,预留一段内存,内核看不见小于物理内存大小,内存管理要求较高

4、malloc 申请内存

调用 malloc 函数时,它沿 free_chuck_list 连接表寻找一个大到足以满足用户请求所需要的内存块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值