Linux内存分配

Linux内存分为三个区段:
DMA内存
常规内存
高端内存

内核只能分配一些预定义的,固定大小字节数组 
1. kmalloc不能分配高端内存

2. 后备高速缓存,是一个内存池,容纳了任意数量的小内存块,块的大小由分配该缓存池时指定。高速缓存的使用统计可以从/proc/slabinfo中获得。

3. 内存池,其实就是一种高速缓存,其会保存某个最小数额的分配块,当超过该最小数额的内存块被释放时,会被返回给系统,如果在此数额之内,则还是会留在这块内存池中。在内存池被销毁时,需要返回所有已分配内存,否则内核会有oops。

4. get_free_page
以页(2的n次方)为单位分配内存,可以有效避免外部碎片

5. vmalloc,用来分配大尺寸内存。因为其会建立页表,所以他的物理内存可能不连续,但是他的虚拟内存一定是连续的。

6. 内核甚至允许在引导时分配内存,这是一个不得已采取的方法,在引导时分配的内存,是没办法由内核的内存管理模块管理的,其接口是alloc_bootmem_xxx

内存技术的区别:
1. kmalloc,__get_free_pages,vmalloc均分配的是虚拟地址。前两个的地址是直接线性映射的,所以虚拟地址和物理地址是一一对应的,而后者是通过页表间接映射的,所以分配时较慢,且不和物理地址一一对应
2. vmalloc不能用于原子上下文,因为他是用kmalloc(GFP_KERNEL)实现的,没有用GFP_ATMIC标志,所以会休眠。