1

mmap用来分配大页面。这很好用,但有时我会接近可用大页面的限制,并且在访问内存时会出现 SIGBUS 错误。但是我不明白mmap如果没有任何内存,为什么首先成功,我不明白为什么/proc/meminfo似乎表明有足够的内存?

4

1 回答 1

2

如果你想知道有多少大页面可用,你需要做

grep Huge /proc/meminfo

然后减去

availablePages = HugePages_Free - HugePages_Rsvd  

那是因为“免费”实际上并不意味着免费。这只是意味着内存还没有被触及。如果availablePages为 0,则不能再成功分配 Huge Pages。所以很有可能,你的内存已经用完了,但是你被可怕的输出弄糊涂了/proc/meminfo

但是,mmap不会失败!...所以也请阅读下一段。

在打开标志的情况下使用mmap分配大页面有一个不幸的缺陷。MAP_NORESERVE这意味着不要保留交换空间。但是,即使系统无法处理,mmap也会成功“分配”大页内存。为了测试是否mmap成功地物理分配内存并使其立即可用是调用mincore()以评估是否每个页面都已成功分配。我做了这样的事情:

  ptr = mmap( ... );
  ...

  uint32_t inMemoryPages = 0;
  for(int j=0;j<numDesiredPages;j++)
  {
       uint8_t flag;
       int s = mincore((uint8_t*)ptr + j * HugePageSize(), 1,&flag);
       // flag is 1 if the page was successfully allocated and in memory
       inMemoryPages += flag;
  }
  if (numDesiredPages != inMemoryPages)
  {
      std::stringstream ss;
      ss << "Unable to fulfill huge page allocation request."
         << " numDesiredPages:" << numDesiredPages
         << " successfulPages:" << inMemoryPages;
      throw std::runtime_error(ss.str());

  }

否则,您的mmap调用可能会成功,然后SIGBUS当您发现您实际上没有足够的大页面内存时,您会获得成功。

于 2016-06-21T21:13:41.050 回答