Linux内存管理

物理内存管理

Linux内核首先把物理内存划分成大小为4K页进行管理,并且系统为每一个物理页都分配了一个struct page的结构体来进行描述,内容包括页面被引用次数,页的虚拟地址等内容。
在页的基础上,内核进一步把页由划分成不同的区,相似特性的页面划分成一组【主要由硬件决定】。

  • ZONE_DMA 能指向DMA操作的页
  • ZONE_NORMAL 正常页 【从物理内存到虚拟内存正常寻址】
  • ZONE_HIGHMEM 高端页【动态映射】

在Linux内核地址空间映射着上述的物理内存,但内核地址空间寻址范围如果比实际的物理内存小,就需要设计一个动态映射区,这样物理内存和内核就建立起关联了。

  • 直接映射区—>ZONE_DMA, ZONE_NORMAL
  • 动态映射区---->ZONE_HIGHMEM

Buddy分配机制

上面已经讲了系统对物理内存的最小管理单位是页,当需要一个小内存空间时,我们就需要分配一个页。例如我们需要20个字节内存,但需要分配一个页4K内存,多次申请回收就产生了内部碎片。同样在需要大内存时,我们需要分配连续多个页,多次申请回收之后就容易产生外部碎片。
这里就引入了页面管理算法来解决,也就是Buddy分配机制。
简单来说就是将大小相同的页框用链表接连起来。每个链表分别代表大小为1,2,4,8,16…1024个连续页形成的页框块。例如其中有一个链表中的元素是大小为8页的内存。这样做的好处是申请内存不够是可以拆分上一级大内存,多个小内存释放之后可以合并成上一级大内存。可以减少碎片产生。

slab机制

到这里内存管理机制还是不够完善,Buddy最小的单位是一页,而我们上述说的内部碎片问题还是没有解决。而slab就是解决这一问题的,将内存按照使用对象大小再进行划分。
对于一些小型的数据结构分配与释放时一种十分常见的操作。这时按照不同的数据结构类型【对象】将内存划分成多个高速缓存组,一个组对于一种对象。高速缓存组又被划分成多个slab,一个slab下面有多个对象。每当要申请这种类型的对象时,就从slab 列表中分配一个出去;而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免内部碎片,同时也大大提高了内存分配性能。

进程地址空间

到现在讲了从物理内存到内核的联系,以及对物理内存管理的两种机制。内存的管理还有一部分就是从内核到用户空间这一部分了。当在用户空间运行一个进程时,每个进程都会有一个独立的空间。这是由于Linux采用了虚拟内存技术,每个进程似乎都拥有整个物理内存。尽管进程可以寻址所有虚拟内存,但不代表它可以访问所有地址,可以被合法访问的称作内存区域。
在内核中会有一个内存描述符mm_struct来表示进程的地址空间。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值