malloc 、calloc、kmalloc、kzalloc、vmalloc、和get_free_page() 等区别
用户/内核 | API名称 | 物理连续? | 大小限制 | 单位 | 场景 | |
用户空间 | malloc/calloc/realloc/free | 不保证 | 堆申请 | 字节 | calloc初始化为0;realloc改变内存大小。 | |
alloca | 栈申请 | 字节 | 向栈申请内存 | |||
mmap/munmap | 将文件利用虚拟内存技术映射到内存中去。 | |||||
brk、sbrk | 虚拟内存到内存的映射。sbrk(0)返回program break地址,sbrk调整对的大小。 | |||||
内 核 空 间 | vmalloc/vfree | 虚拟连续 物理不定 | vmalloc区大小限制 | 页 VMALLOC区域 | 可能睡眠,不能从中断上下文中调用,或其他不允许阻塞情况下调用。 VMALLOC区域vmalloc_start~vmalloc_end之间,vmalloc比kmalloc慢,适用于分配大内存。 | |
slab | kmalloc/kcalloc/krealloc/kfree | 物理连续 | 64B-4MB (随slab而变) | 2^order字节 Normal区域 | 大小有限,不如vmalloc/malloc大。 最大/小值由KMALLOC_MIN_SIZE/KMALLOC_SHIFT_MAX,对应64B/4MB。 从/proc/slabinfo中的kmalloc-xxxx中分配,建立在kmem_cache_create基础之上。 | |
kmem_cache_create | 物理连续 | 64B-4MB | 字节大小,需对齐 Normal区域 | 便于固定大小数据的频繁分配和释放,分配时从缓存池中获取地址,释放时也不一定真正释放内存。通过slab进行管理。 | ||
伙伴系统 | __get_free_page/__get_free_pages | 物理连续 | 4MB(1024页) | 页 Normal区域 | __get_free_pages基于alloc_pages,申请的大小是一整页,但是限定不能使用HIGHMEM。和kmalloc最终调用实现是相同的,只不过在调用最终函数时所传的flag不同 | |
alloc_page/alloc_pages/free_pages | 物理连续 | 4MB | 页 Normal/Vmalloc都可 | CONFIG_FORCE_MAX_ZONEORDER定义了最大页面数2^11,一次能分配到的最大页面数是1024。 |
关于kmalloc等实现可以通过网络查询。
linux内存分布如下:
对于提供了MMU(存储管理器,辅助操作系统进行内存管理,提供虚实地址转换等硬件支持)的处理器而言,Linux提供了复杂的存储管理系统,使得进程所能访问的内存达到4GB。
进程的4GB内存空间被人为的分为两个部分--用户空间与内核空间。用户空间地址分布从0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB为内核空间。
内核空间中,从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页框表mem_map等等),比如我们使用 的 VMware虚拟系统内存是160M,那么3G~3G+160M这片内存就应该映射物理内存。在物理内存映射区之后,就是vmalloc区域。对于 160M的系统而言,vmalloc_start位置应在3G+160M附近(在物理内存映射区与vmalloc_start期间还存在一个8M的gap 来防止跃界),vmalloc_end的位置接近4G(最后位置系统会保留一片128k大小的区域用于专用页面映射)。