为啥 malloc 不能在 FreeBSD-x64 内核空间分配大内存?
Posted
技术标签:
【中文标题】为啥 malloc 不能在 FreeBSD-x64 内核空间分配大内存?【英文标题】:Why malloc can not allocate huge memory in FreeBSD-x64 kernel space?为什么 malloc 不能在 FreeBSD-x64 内核空间分配大内存? 【发布时间】:2015-08-07 14:35:20 【问题描述】:我尝试在 FreeBSD-x64 内核空间分配大内存,但它返回 NULL。
void *ptr = NULL;
static int
init_module(void)
u_long SIZE_ALLOC = ((u_long)2500 * 1024 * 1024);
ptr = malloc(SIZE_ALLOC, M_DEVBUF, M_NOWAIT);
if( !ptr )
uprintf("Allocation has been failed!!\n");
return (0);
我有足够的RAM(8 [GB]
)并且我有足够的空闲内存,但它返回NULL
。
如果我在用户空间运行此代码,它可以正常工作并捕获大量内存,但对于内核空间它会失败!!!!
错误在哪里,我该如何解决?
【问题讨论】:
64 位进程?它将尝试分配一个连续的内存范围。如果有碎片,它会失败,即使当您将所有单独的空闲空间相加时它总共有足够的空闲空间。 我认为内核空间的上限不一定要与您系统的RAM空间匹配。好奇的问题,为什么需要分配这么大的内存? @Robinson 是的,可能它正在寻找一个连续的内存范围。 特殊内存池需要它。 是的,我需要连续的内存范围。为什么这在用户空间可以正常工作,但对于内核空间有问题?我有大约 6 [GB] 的可用空间。 【参考方案1】:当您使用M_NOWAIT
标志时,您只能获得 NULL 结果。
这基本上意味着现在没有这么多可用内存。
试试M_WAITOK
。我也会添加一个M_NODUMP
。结果是模块 init 进程可能会进入休眠状态,直到释放足够的内存。
内核malloc分配物理内存,不分页。参见“4.4BSD 操作系统的设计与实现”中的memory management section。在“FreeBSD 操作系统的设计与实现”中可以逐字找到相同的文本。
您可以使用sysctl vm.phys_free
查看可用的物理内存量。在我的机器上显示:
FREE LIST 0:
ORDER (SIZE) | NUMBER
| POOL 0 | POOL 1 | POOL 2
-- -- -- -- -- -- -- --
12 ( 16384K) | 0 | 0 | 0
11 ( 8192K) | 0 | 0 | 0
10 ( 4096K) | 0 | 0 | 0
9 ( 2048K) | 0 | 0 | 0
8 ( 1024K) | 0 | 0 | 0
7 ( 512K) | 0 | 0 | 0
6 ( 256K) | 0 | 0 | 0
5 ( 128K) | 33 | 4 | 0
4 ( 64K) | 2137 | 112 | 0
3 ( 32K) | 18136 | 116 | 5
2 ( 16K) | 20492 | 47 | 11111
1 ( 8K) | 2817 | 24 | 23422
0 ( 4K) | 1396 | 32 | 4956
如果我正确解释这一点,我无法使用内核 malloc 分配 >128K 的连续块。
【讨论】:
我检查了 M_WAITOK 但 FreeBSD 很恐慌。我对 M_NODUMP 没有任何想法!!!!!! 那么可能没有足够的内存来做你想做的事。【参考方案2】:无论你拥有什么 RAM,它都不会增加内核使用的 RAM 的比例,在相同比例的巨大 RAM 中。通常内核有 1GB RAM 用于其功能(我不太确定具体数量)。因此,由于可用 RAM 有限,在内核模式下如此巨大的分配失败并不奇怪
【讨论】:
不,内核没有任何限制。我认为连续的巨大内存范围在内核空间中存在问题。 连续范围肯定是个问题。在我看来,由于我了解内核空间的一些限制,因此在内核空间中拥有非常大的连续范围非常困难。您自己在用户空间中说过,它会成功,然后为什么会发生。以上是关于为啥 malloc 不能在 FreeBSD-x64 内核空间分配大内存?的主要内容,如果未能解决你的问题,请参考以下文章