为啥 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 内核空间分配大内存?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在malloc中不调用构造函数? [复制]

Delphi - 为啥我不能在 64 位中安装我的组件?

为啥 VFP .NET OLEdb 提供程序不能在 64 位 Windows 中工作?

为啥在 C 中需要使用 malloc 进行动态内存分配?

如果存在 VLA,为啥仍然需要 malloc? [复制]

为啥我不能在 ATMEGA64A-AU 串口中输入命令?