Linux内存管理——内核内存管理

前言    

linux内存管理可以分为两部分,内核内存管理,进程内存管理。由于一些条件的限制,比如内核分配内存时不能睡眠,不能像用户空间那样奢侈的使用内存,内核的内存分配与用户空间的内存分配是不太一样的,本文据此大概讨论下内存管理机制。

内核把页作为内存管理的基本单元,尽管cpu的最小可寻址单位为字节。内存管理单元(MMU)用页表对页进行管理,并且负责将物理内存映射为虚拟内存。

一般体系结构不同,对应的页的大小也是不一样的,比如32为x86的环境,页的大小通常为4KB,64位体系结构一般支持8KB大小的页。所以,如果对于一台有1GB物理内存的32位x86环境,物理内存会被划分为262144个页。内核对每个页用一个struct page来维护。

由于硬件的限制,比如:

  1. 一些硬件只能使用某些特定的地址来进行DMA(直接内存访问)
  2. 一些体系结构的实际物理内存比虚拟寻址范围还大,这样就有部分内存不能永久映射为虚拟地址

所以内核必须区分对待这些页。为此,内核又将页划分为了区。内核使用struct zone结构维护区。

区的划分
名称描述
ZONE_DMA这个区包含的页用来执行DMA操作
ZONE_DMA32这个区包含的页用来执行DMA操作,且这些页面只能被32位设备访问

ZONE_NORMAL

这个区包含的时能被正常映射的页
ZONE_HIGHEM高端内存,其中的页不能被永久的映射到内核地址空间

在32位x86体系上,可访问的虚拟地址空间大小为4GB,其中前1~3G留给用户空间使用,最后3~4G给内核空间使用,也即内核虚拟地址的寻址空间只有1GB大小。所以在1G里,先把DMA占用的内存划分出去(一般时前16MB),再预留128MB用来映射高端内存,剩下的才是ZONE_NORMAL的。x86-x64体系结构可以映射和处理64位地址空间,所以不存在高端内存区。

某些内存分配可能需要直接内存访问,所以只能从DMA区获取内存;大部分的内存分配对区并没有要求,那么内核会优先从常规区进行内存分配,常规区内存不足的,会考虑从其他区申请内存,如高端内存。

内存分配接口

void * kmalloc(size_t size, gfp_t flags);    void * kfree(const void *ptr);

获得以字节为单位的内存,且保证物理地址连续,虚拟地址当然也是连续的。通过kfree释放。

void * vmalloc(unsigned long size);    void vfree(const void *addr);

获得以字节为单位的内存,保证虚拟地址连续,但物理地址不一定连续。它通过分配非连续的物理内存块,再修正页表,把内存映射到虚拟地址空间的连续区域中来做到这一点。

一般只有硬件设备才需要得到连续的物理内存,因为硬件设备根本不知道什么是内存管理单元,不理解什么是虚拟地址;其它大部分情况下,只需要连续的虚拟内存即可,对物理内存是否连续没有要求。尽管如此,很多代码依旧使用了kmalloc分配内存而不是vmalloc,原因是vmalloc为了把物理内存不连续的页转换为虚拟空间里连续的页,必须专门为此建立页表项并对每个页一一映射,这样导致比直接内存映射更大的TLB抖动(缓存虚拟地址到物理地址映射关系的硬缓冲区)。所以,通常只有在需要连续的大块内存时,才使用vmalloc。

slab层

分配与释放数据结构是内核中最普遍的操作了,然而频繁的分配与回收会导致大量的内部碎片,所以开发经常需要用到空闲链表。即提前分配好的数据结构块,需要数据结构实例时,从空闲链表获取,不需要时,放回空闲链表中,而不是释放内存,slab层(也即slab分配器)就是做这个的。

slap层把不同的对象划分为高速缓存组,其中每个组都存放不同类型的对象,每个组就相当于是一个空闲链表。顺便一提,kmalloc接口也是建立在slab层之上,使用了一组高速缓存。

每个slab都包含一些对象成员,这些slap有三种状态:(没有空闲对象)、部分空(有部分空闲对象)、(全部空闲)。当内核某个部分需要一个新的对象时,先在部分空的slab中进行分配。如果没有部分空的slab,就在空的slab中进行分配。如果连空的slab也没有,那就重新创建一个新的slab。这样的策略可以提高分配的效率,以及减少内存碎片。内核使用struct slab结构来维护slab.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fireplusplus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值