2016-06-21 68 views
0

我正在使用mmap來分配巨大的頁面。這工作正常,但有時我會接近可用大頁面的限制,並且在訪問內存時遇到SIGBUS故障。但我不明白爲什麼mmap成功在第一個地方,如果沒有任何內存,我不明白爲什麼/proc/meminfo似乎表明,有足夠的內存?即使HugePages_Free爲正也可以在mmap後獲得SIGBUS

回答

1

如果你想知道有多少巨大的頁面是如何可用,你需要做的

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當你發現你實際上並沒有足夠龐大的頁面內存後。

相關問題