Linux内存管理 —— 内核态和用户态的内存分配方式

本文详细介绍了Linux内存管理,包括内核态的buddy系统和slab分配器,以及用户态的"lazy allocation"机制。buddy系统管理物理内存,slab对内存进行二次管理,满足小块内存需求。用户态申请内存时采用lazy模式,通过COW减少系统调用。此外,文章还讨论了OOM处理和满足DMA连续内存需求的方法,如预分配内存、IOMMU和CMA技术。
摘要由CSDN通过智能技术生成

1. 使用buddy系统管理ZONE

我的这两篇文章buddy系统slab分配器已经分析过buddy和slab的原理和源码,因此一些细节不再赘述。

所有zone都是通过buddy系统管理的,buddy system由Harry Markowitz在1963年提出。buddy的工作方式我就不说了,简单来说buddy就是用来管理内存的使用情况:一个页被申请了,别人就不能申请了。通过/proc/buddyinfo可以查看buddy的内存余量。

由于buddy是zone里面的一个成员,所以每个zone都有自己的buddy系统来管理自己的内存(因此,buddy管理的也是物理内存哦)。

[jchen@ubuntu]my_code:$ cat /proc/buddyinfo 
Node 0, zone      DMA      9     15      1      1      4      1      1      2      1      1      0 
Node 0, zone   Normal    157    902    332     76     77     77     47     23     11      1      0 
Node 0, zone  HighMem      1      2     13      3      3      2      4      0      0      0      0 

buddy的问题就是容易碎掉,即没有大块连续内存。对应用程序和内核非线性映射没有影响,因为有MMU和页表,但DMA不行,DMA engine里面没有MMU,一致性映射后必须是连续内存。

可以通过alloc_pages(gfp_mask, order)从buddy里面申请内存,申请内存大小都是2^order个页的大小,这样显然是不满足实际需求的。因此,基于buddy,slab(或slub/slob)对内存进行了二次管理,使系统可以申请小块内存。

Slab先从buddy拿到数个页的内存,然后切成固定的小块(称为object),再分配出去。从/proc/slabinfo中可以看到系统内有很多slab,每个slab管理着数个页的内存,它们可分为两种:一个是各模块专用的,一种是通用的

在内核中常用的kmalloc就是通过slab拿的内存,它向通用的slab里申请内存。我们也就知道,kmalloc只能分配一个对象的大小,比如你想分配40B,实际上是分配了64B。在include/linux/kmalloc_sizes.h可以看到通用cache的大小都有哪些:

#if (PAGE_SIZE == 4096)
    CACHE(32)
#endif
    CACHE(64)
#if L1_CACHE_BYTES < 64
    CACHE(96)
#endif
    CACHE(128)
#if L1_CACHE_BYTES < 128
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值