Linux1.0 kmalloc kfree_s分析

来源:互联网 发布:新红帆网络 编辑:程序博客网 时间:2024/06/07 02:08
                        kmalloc分析    kmalloc内存分配函数是Linux内核中动态内存管理中非常重要的函数,在这篇博客中主要来分析内核当中动态内存的分配和释放过程。    首先来介绍kmalloc和kfree_s的基本原理,在Linux内核当中内存

的管理采用的是分页管理方式,即以页为单位,每页的大小4KB。在系
统当中内核每次对动态内存的申请大小是不确定的,就是你可以申请
的大小可以是32KB,64KB,128KB,,4080KB,现暂且将这个大小
称为size,对于每种大小的内存申请,如果已有的空闲块被用完,则内核申请一页新的内存(4KB),在该页内存中的起始处,会存放一个页描述符,页描述符中记录该内存块中分成的小块的使用情况以及下一块用来分配这样size大小的物理块,然后将该页的剩下内存按照申请块的大小和每块的块头平均分成若干块,在这里的块头是用来记录各块之间的链接关系,块头的下部分内存才是被kmalloc分配出去的内存。
介绍了分配的基本原理之后,再来介绍内核当中关于kmalloc的几个重要结构体:
1、每块内存的块头
struct block_header {
unsigned long bh_flags; /物理页中分配的块的状态/
union {
unsigned long ubh_length; /被使用时记录实际使用大小/
struct block_header fbh_next; /空闲时下一个块的大小*/
} vp;
};
2、分配size大小的物理块页描述符
struct page_descriptor {
struct page_descriptor *next;
struct block_header *firstfree;
int order; /这一页分配的是多大块号/
int nfree; /一页中空闲块的数量/
};
3、记录内核中分配的内存大小以及一页内存中可以分配该种size大小的块的数量,同时记录了也记录了分配该size大小的物理页的地址
struct size_descriptor {
struct page_descriptor firstfree; /分配size大小块的物理页地址*/
int size;
int nblocks; /一页总共能分配多少块/

    int nmallocs;                       /*已经使用size大小的块有多少块*/    int nfrees;    int nbytesmalloced;                 /*实际分配的字节数*/    int npages;                         /*使用了多少页*/};4、struct size_descriptor的一个数组,初始化各种可以分配的大小以及一页可以分配的小块的数量。struct size_descriptor sizes[] = {     { NULL,  32,127, 0,0,0,0 },    { NULL,  64, 63, 0,0,0,0 },    { NULL, 128, 31, 0,0,0,0 },    { NULL, 252, 16, 0,0,0,0 },    { NULL, 508,  8, 0,0,0,0 },    { NULL,1020,  4, 0,0,0,0 },    { NULL,2040,  2, 0,0,0,0 },    { NULL,4080,  1, 0,0,0,0 },    { NULL,   0,  0, 0,0,0,0 }};这几个结构体在内存当中的关系可以用下图来表示

这里写图片描述

            分配之后就是内存块的释放了,当给出一个释放地址时,可以算出该地址所在的物理块然后取物理块开始处的页描述符,                首先将释放的块添加到该页的空闲块链的链首,然后将所在的物理页放在size大小对应的物理页链表的链首,方便                下次分配时寻找空闲块。如果所在的整个物理块是空闲的则将整个物理块释放。详细的代码注释:https://github.com/wanggx/Linux1.0
0 0
原创粉丝点击