KMALLOC 只分配页面大小的内存还是可以分配更少的内存?kmalloc 可以分配的大小是多少?我在哪里可以找到它的描述,因为我到处看它并没有真正说明它分配了多少内存?我想知道 KMALLOC 分配的实际大小是多少。它是否分配 2 的幂大小?它只是从准备好的缓存中找到空闲对象吗?
3 回答
我的理解是:内核在处理系统的物理内存,只有page-sized chunks才有;因此,当您调用时,您kmalloc()
只会得到某些预定义的、固定大小的字节数组。
您获得的实际内存取决于系统的体系结构,但 kmalloc 可以处理的最小分配是 32 或 64 字节。您将从通话中恢复到kmalloc()
至少与您要求的一样多的内存(通常更多)。通常,您不会获得超过 128 KB(同样,取决于架构)
要获取系统的页面大小(以字节为单位),您可以执行以下命令:
getconf PAGESIZE
或者
getconf PAGE_SIZE
有关最大页面大小的信息位于 /usr/src/linux/include/linux/slab.h
是的,页面大小通常是 2 的幂,但同样,你不会得到你想要的东西,但会多一点。
您可以使用如下代码:
void * stuff;
stuff = kmalloc(1,GFP_KERNEL);
printk("I got: %zu bytes of memory\n", ksize(stuff));
kfree(stuff);
要显示分配的实际内存量:
[90144.702588] I got: 32 bytes of memory
这完全取决于内核中使用的分配器。板坯、竹节或粗杆。请参阅以下内核配置变量:
CONFIG_SLAB
CONFIG_SLUB
CONFIG_SLOB
以上所有分配器都使用MAX_ORDER和PAGE_SHIFT来决定 kmalloc() 的最大限制
SLAB 分配器支持的最大 kmalloc 大小为 32 MB (2^25) 或最大可分配页顺序(如果小于 32 MB)。
#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
(MAX_ORDER + PAGE_SHIFT - 1) : 25)
#define KMALLOC_SHIFT_MAX KMALLOC_SHIFT_HIGH
SLUB 直接将请求分配到 order-1 页面 ( PAGE_SIZE*2
)。较大的请求被传递给页面分配器。
#define KMALLOC_SHIFT_HIGH (PAGE_SHIFT + 1)
#define KMALLOC_SHIFT_MAX (MAX_ORDER + PAGE_SHIFT)
SLOB 将所有大于一页的请求传递给页分配器。不需要 kmalloc 数组,因为可以从同一页分配不同大小的对象。
#define KMALLOC_SHIFT_HIGH PAGE_SHIFT
#define KMALLOC_SHIFT_MAX 30
kmalloc() 可分配的最大大小为
#define KMALLOC_MAX_SIZE (1UL << KMALLOC_SHIFT_MAX)
kmalloc() 的最小可分配大小为
#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW)
slab 的默认KMALLOC_SHIFT_LOW
值为 5,slub 和 slob 的默认值为 3。
kmalloc()
您可以通过以下方式查看int 系统使用的一些常见尺寸:
cat /proc/slabinfo | grep kmalloc
比考虑 kmalloc 是否可以分配少于一页更重要的是它是否可以分配多于一页的问题:如果您kmalloc()
在原子上下文中调用(带有GFP_ATOMIC
标志),它不能也不会尝试非常在内存中很难找到连续的页面,所以如果你的内存非常碎片化,并且你的分配顺序很高(allocation size → pagesize*2^(allocation order))
,分配可能会失败。因此,在原子上下文中,大分配可能会失败。
在另一个关于最大 AF_UNIX 数据报大小的 SO question中,有一个 order 7 (512 Kb) 分配失败的示例。