я использую mmap
выделить огромные страницы. Это работает нормально, но иногда я достигаю предела доступных огромных страниц и получаю ошибки SIGBUS при доступе к памяти. Но я не понимаю почему mmap
в первую очередь, если не было памяти, и я не понимаю, почему /proc/meminfo
кажется, показывает, что памяти достаточно?
Если вы хотите узнать, сколько огромных страниц доступно, вам нужно сделать
grep Huge /proc/meminfo
а затем вычесть
availablePages = HugePages_Free - HugePages_Rsvd
Это потому, что «бесплатно» на самом деле не означает бесплатно. Это просто означает, что память еще не была затронута. Если availablePages
0, то вы больше не можете выделить больше огромных страниц. Так что, скорее всего, вы не хватило памяти, но вы запутались из-за ужасного выхода /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
позже, когда вы узнаете, что у вас не было достаточно огромной памяти страниц.
Других решений пока нет …