2017-07-11 109 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