2017-07-11 108 views
0

我想指出我是新來的,所以我試着最好地理解/解釋它。內存分配閾值(mmap vs malloc)

我基本上試圖找出是否有可能由於我的項目的內存限制保持內存分配低於閾值。

下面是如何內存是目前使用第三方libsodium分配:

alloc_region(escrypt_region_t *region, size_t size) 
{ 
    uint8_t *base, *aligned; 
#if defined(MAP_ANON) && defined(HAVE_MMAP) 
    if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE, 
#ifdef MAP_NOCORE 
           MAP_ANON | MAP_PRIVATE | MAP_NOCORE, 
#else 
           MAP_ANON | MAP_PRIVATE, 
#endif 
           -1, 0)) == MAP_FAILED) 
     base = NULL; /* LCOV_EXCL_LINE */ 
    aligned = base; 
#elif defined(HAVE_POSIX_MEMALIGN) 
    if ((errno = posix_memalign((void **) &base, 64, size)) != 0) { 
     base = NULL; 
    } 
    aligned = base; 
#else 
    base = aligned = NULL; 
    if (size + 63 < size) 
     errno = ENOMEM; 
    else if ((base = (uint8_t *) malloc(size + 63)) != NULL) { 
     aligned = base + 63; 
     aligned -= (uintptr_t) aligned & 63; 
    } 
#endif 
    region->base = base; 
    region->aligned = aligned; 
    region->size = base ? size : 0; 

    return aligned; 
} 

因此,舉例來說,目前這要求posix_memalign分配(例如)32MB內存。 32mb超過了我給予我的'內存上限'(但不會因爲內存容量更大而拋出內存警告,它只是我'允許'使用的內存)

從一些Google搜索中,我處於我可以使用mmap和虛擬內存的印象。 我可以看到,上面的函數已經實現了一些mmap,但從未被調用過。

是否有可能轉換上面的代碼,以便我永遠不會超過我的30mb內存限制?

從我的理解,如果這個分配將超過我的空閒內存,它會自動分配在虛擬內存?那麼我是否可以強迫這種事情發生並假裝我的可用空間比可用空間低?

任何幫助表示讚賞

UPDATE

/* Allocate memory. */ 
    B_size = (size_t) 128 * r * p; 
    V_size = (size_t) 128 * r * N; 
    need = B_size + V_size; 
    if (need < V_size) { 
     errno = ENOMEM; 
     return -1; 
    } 
    XY_size = (size_t) 256 * r + 64; 
    need += XY_size; 
    if (need < XY_size) { 
     errno = ENOMEM; 
     return -1; 
    } 
    if (local->size < need) { 
     if (free_region(local)) { 
      return -1; 
     } 
     if (!alloc_region(local, need)) { 
      return -1; 
     } 
    } 
    B = (uint8_t *) local->aligned; 
    V = (uint32_t *) ((uint8_t *) B + B_size); 
    XY = (uint32_t *) ((uint8_t *) V + V_size); 
+0

恐怕不容易回答....例如文件讀取或寫入通常mmap。 –

+1

上面的代碼不會嘗試分配超過30Mb的__你無法提問__。是不是有一個原因,你不能避免首先要求太多的記憶? – Useless

+0

我打電話給加密方法,由於內存問題導致終止,因爲我超過了我給定的30mb閾值。所以我追溯到這個函數的分配。你是說如果我只是告訴它分配20MB它仍然可以執行只有20MB分配的操作?我已更新我的原始帖子,以顯示調用alloc_region – nicwhitts

回答

1

我基本上是想弄清楚如果能夠保持在閾值內存分配,由於我的項目的內存限制。

在Linux或POSIX系統,你可以考慮使用setrlimit(2)RLIMIT_AS

  This is the maximum size of the process's virtual memory 
      (address space) in bytes. This limit affects calls to brk(2), 
      mmap(2), and mremap(2), which fail with the error ENOMEM upon 
      exceeding this limit. 

超過這個限制,mmap會失敗,因此將呼叫失敗的實例malloc(3)這觸發了mmap的特定使用。


我的印象是我可以使用mmap

注意malloc(3)將調用mmap(2)(或有時sbrk(2) ...)從內核檢索(虛擬)內存,從而增長你的virtual address space。但是,malloc通常更喜歡先前重新使用free -d內存(如果可用)。並且free通常不會調用munmap(2)來釋放內存塊,但更願意將它保留爲將來的malloc -s。實際上,大多數C標準庫在「小」和「大」分配之間進行分離(實際上,對於千兆字節,將使用malloc,對應的free將立即爲mmap)。請參閱mallopt(3)madvise(2)。如果您需要將某些頁面(通過mmap獲取)鎖定爲物理 RAM,請考慮mlock(2)

也請參閱this答案(解釋特定進程使用的RAM的概念並不那麼容易)。 (包括memory leaks)使用valgrind