在 mmap 之后获得 SIGBUS 对于大页面,即使HugePages_Free是积极的
Getting SIGBUS after mmap for Huge Pages, even though HugePages_Free is positive
我正在使用mmap
来分配巨大的页面。这工作正常,但有时我接近可用大页面的限制,并且在访问内存时出现 SIGBUS 错误。但是我不明白,如果没有记忆,为什么mmap
首先成功,我不明白为什么/proc/meminfo
似乎表明有足够的记忆?
如果你想知道有多少大页面可用,你需要做
grep Huge /proc/meminfo
然后减去
availablePages = HugePages_Free - HugePages_Rsvd
这是因为"免费"实际上并不意味着免费。这只是意味着内存还没有被触及。如果availablePages
为 0,则无法成功分配更多大页面。 所以很有可能,你已经用完了内存,但你对/proc/meminfo
的可怕输出感到困惑。
但是,mmap
不会失败!所以也读下一段。
在打开MAP_NORESERVE
标志的情况下,使用mmap
分配大页面存在一个不幸的缺陷。这意味着不要保留交换空间。但是,即使系统无法"分配"巨大的页面内存,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
。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 为什么控制台要求输入,即使代码中没有输入
- g++ 说函数不存在,即使包含正确的标头
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 为什么可以将左值传递给"std::async",即使它引用了右值
- muQueue.front() 给出了 const 实例,即使我没有将其标记为 const
- 为什么static_assert错误:即使我传递常量"expression must have a constant value"?
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 即使使用调试编译标志,表达式也是"optimized out"
- 无法打开 fstream C++文件,即使它与 .cpp 位于同一位置
- 这些是什么样的错误?即使我不在 Linux 上工作,我也遇到了 Linux 错误
- Qt:"Q3DScatter"即使包含在内也无法识别
- 当我使用自定义类型创建动态数组时,即使使用字符串,它似乎也不起作用
- 为什么文件不是由 F 流创建的,或者即使它是输出只是垃圾值?
- 即使没有调用这个递归函数,它是如何工作的?