【UNIX】内核对内核空间内存的管理以及对用户进程的堆内存分布
常用的内核内存分配函数
1)_get_free_pages是最原始的内存分配方式,至二级从伙伴系统中获取原始页框,返回值为第一个页框的起始地址。_get_free_pages在实现上只是封装了alloc_pages函数,而alloc_pages分配的长度为1<
2)Kmem_cache_alloc是基于slab分配器的一种内存分配方式,适用于反复分配释放同一大小内存的场合。首先用Kmem_cache_alloc从该高速缓存区域中获取新的内存块。在2.6内核中一次最多能申请1<< 5*4KB也就是128KB连续物理内存
3)Kmalloc是内核中常见的一种内存分配方式,他们通过调用kmem_cache_alloc函数实现,kmalloc一次最多申请128KB连续的物理内存,如果大于128KB则编译不通过
4)Vmalloc 前面几种分配方式都是物理连续的,能保证较低的平均访问时间。但是在某些场合,对内存区的请求不是很频繁,较高的内存访问也可以接受,这就可以分配一段线性连续,物理不连续的地址,带来的好处就是可以分配较大的内存,对于vmalloc分配的内存空间大小一般没有限制,但是一般内存大小最好不要大于1GB
5)Dma_alloc_coherent ,DMA是一种硬件机制,允许外围设备和主存之间直接传输io数据,而不需要CPU的参与,使用DMA机制能大幅度提高与设备的通信的吞吐量
6)Ioremap
Void *ioremap(unsigned long offset ,unsigned long size )
Ioremap是一种更直接的内存分配方式,使用时直接指定物理起始地址和需要分配的内存大小,然后将该段物理地址映射到内核地址空间,Ioremap用到的物理地址事先是知道确定的,和上面的几种方式不同,并不是分配一段新的物理地址内存,ioremap多用于设备驱动,实现了物理地址和虚拟地址的相互转化,这种机制在Linux内核设备驱动中起着重要的作用。可以让CPU通过虚拟地址的访问间接的访问外部设备的io空间。
用户进程的堆内存的分布
extern void *malloc(unsigned int num_bytes);
Malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void*?类型。void* 表示未确定类型的指针。C规定,void* 类型可以强制转换为任何其它类型的指针。
功能:分配长度为num_bytes字节的内存块
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:
int *p;
p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);
或:
int* parr;
parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;
而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。
int* p;
p = (int *) malloc (sizeof(int)*128);//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中
分配机制
malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。