【内存管理】心得

本文详细介绍了内存分配的几种方式,包括slab分配解决空闲内存问题、buddy伙伴管理处理内存碎片,以及kmalloc、vmalloc、kmem_cache等函数的作用。还涵盖了页框分配调度、虚实转换和内存释放的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

散乱的小知识点:
*slab分配:*小块内存使用完不直接释放,而被存储到存储池留作下次使用,避免频繁创建后销毁对象带来的负载;用来解决空闲内存大,使用内存小的问题。又称为基于对象的分配
*buddy伙伴管理:*存储是分zone的,在一个不够用的时候,从另一个里面去拿;用来解决外部分片的问题(即使用内存大,造成使用后的空闲内存不连续,靠的的阶进行的合并与分配),又称为基于页面的分配
kmalloc: 内核虚拟地址重新映射,线性关系,物理地址与虚拟地址连续分配,直接分配的物理页框。这个函数在slab系统启动后才可以用
*vmalloc:*分配大空间,物理地址分配可以不连续,按字节分配,最终也是调用alloc_pages_node 进行分配
kmem_cache_alloc 特定类型的内核缓存,数据结构是 kmem_cache, 在后面加 init, create, alloc等表示初始化、创建、分配、缓存增长、释放对象、销毁缓存。
页框: PGd -PUD-PMD-PTE-PAGE()
页分配时的调度:通过page_min,page_high,pages_low 进行控制。当空闲页面小于page_min时,表明Zone非常却页,页面回收压力很大,当大于page_high时是理想状态,当小于pages_low时,存在页换到硬盘,开始释放回收页面,即唤醒kswapd守护进程,用来获得更多的空闲内存,方法为通过缩减内核缓存、进行页面回收(写回页或换出较少的页)。记得在PAGE的结构中有标记页的状态(可回收页,不可回收页,可移动页)
内存的珍稀度: DMA供外设系统使用,最为珍贵,Normal保存内核的数据结构,High 作映射的,无所谓

内存分配的函数
alloc_pages(mask, order) #分配多页 主要函数,不论分配虚拟地址还是实例page。
alloc_page(mask) #只分配一页
get_zeroed_page(mask) #分配一页并填0
以上返回page实例
__get_free_pages(mask, order)
__get_free_page(mask)
以上返回虚拟地址
get_dma_pages(gfp_mask, order)

由于所有的分配函数均调用alloc_pages,重点看它,这个函数里面有一个重点的发射台函数–alloc_pages_node, 心脏函数 __alloc_pages_nodemask。
虚实转换函数就是 virt_to_page page_to_virt 函数

内存释放
free_page(struct page *)
free_pages(struct page *, order)
释放page实例
__free_page(addr)
__free_pages(addr, order) 重点调用函数
释放虚拟地址

补充4点,
1.上述函数需用到 _bitwise 进行按位操作,用来确保大小端数据不会混合运算,上文提到的gfp 可以是 GFP_DMA, GFP_HIGHMEN, GFP_DMA32, GFP_MOVABLE .他们之间会进行 bitwise

2.涉及到的inline内联函数,与define不同,inline用于实现,不用于声明,即两者的时机不同,一个在编译阶段,一个在运行阶段。inline会将代码直接放到使用代码中,造成代码膨胀,类似一种静态链接。
3. likely 与 unlikely 是考虑了CPU的流水线指令,好像是3层的。所以在处理if判断语句时,被likely 修饰的语句有较大的概率取真值,被unlikely修饰的较大概率取假,这就加快了一些概率程序的运行,如驱动程序的错误警告
4. 管理虚拟地址与page的结构是
page_adress_map{
struct page *page; 全局的mem_map
void * virtual; 表示内核虚拟地址空间中的位置
struct list_head list
}

struct mm_struct {

start_brk 堆的起始地址,不便
brk 堆的结束地址 变的

arg_start
arg_end

env_start
env_end
mmap_base 虚拟地址空间中用于内存映射的起始地址 **这个用在哪儿?**
task_size 对应进程的地址空间长度
struct vm_area_struct *mmap; 表示虚拟内存区域列表
struct rb_root mm_rb;
struct vm_area_Struct *mmap_cache 表示赏赐find_vm 的结果

}

vm_area_struct 区域由红黑书管理
indoe 特定于文件数据结构
file 特定于进程
地址空间是优先树的基础,优先树包含了相关的vm_atra_Struct 实例

struct vm_area_struct {
addr :虚拟地址的起始点
size: 区域的长度
flags: 内存区域的标识
page
phys_addr 可以用ioremap 进行映射
}
ioremap 是将物理地址、系统总线用于ID操作的内存块映射到内核的地址空间,用于外设地址通信,暴露给内核的其它部分

问题:考虑3个映射关系
虚拟物理地址 页表 线性映射
进程的一个内存区域 与 虚拟内存页地址 通过vm_area_struct 即可
物理内存页 与 该页所属的进程 page结构里面

boot到kernel从stext开始
1, 内核装载后的地址 物理内存与虚拟内存1:1影射
boot中使用的内存 也是1:1映射
2,entrey maapping
清空boot下的映射,建立临时映射用来初始化
3,mmu init
产生mem-map 结构 用来做地址映射进行虚实转换,控制内存访问权限,控制内存属性
4‘paging init
进行分页管理,分页pfn 页框对应一个page,放在mem-map里面
5’mem-init
释放所有bootmem
进行buddy
6,初始化内核内部用于小块内存的分配
slab分配
7‘vmalloc- init
8’用户态init
9‘用户态shell

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值