如何懒惰分配归零内存?

时间:2011-11-11 10:19:45

标签: c linux memory-management

根据我的理解,我必须在callocmalloc之间进行选择,mmap可以分配零内存,calloc可以根据需要分配内存。

是否有兼具这两种属性的功能?也许直接打电话给{{1}}?

如果有可能,为什么{{1}}不这样做?

5 个答案:

答案 0 :(得分:4)

有一些机制可以从操作系统获取预归零内存:

mmap(2)的{​​{1}}标志强制将内容初始化为零。

POSIX共享内存段也可以为零

  • MAP_ANONYMOUS为您提供文件描述符
  • shm_open(3)“你想要的文件”
  • ftruncate(2)将“文件”放入您的地址空间

内存预先归零:

mmap(2)

此内存似乎在使用时归零: This volume of IEEE Std 1003.1-2001 specifies that memory objects have initial contents of zero when created. This is consistent with current behavior for both files and newly allocated memory. For those implementations that use physical memory, it would be possible that such implementations could simply use available memory and give it to the process uninitialized. This, however, is not consistent with standard behavior for the uninitialized data area, the stack, and of course, files. Finally, it is highly desirable to set the allocated memory to zero for security reasons. Thus, initializing memory objects to zero is required. 函数mm/shmem.c

shmem_zero_setup()

答案 1 :(得分:3)

如果您正在尝试使用malloc模拟calloc(即使用malloc但接收归零内存),那么可以使用memset执行此操作:

foo = (char*)malloc(BLOCK_SIZE);
memset(foo,'\0',BLOCK_SIZE);

然而,这是一个坏主意(它比calloc慢,请参阅:Why malloc+memset is slower than calloc?)并且由于Fritschy's answer中所述的原因,不会导致您引用的“延迟分配”。 / p>

答案 2 :(得分:0)

callocmalloc相同,但正如您所说,它将分配的内存归零,并且它接受两个参数 - (NumberOfElements, ElementSize)。所以

malloc(size);

相当于

calloc(1, size);

除了后者提供归零内存。

您所谈论的“按需”分配内存是什么?

答案 3 :(得分:0)

calloc在概念上与malloc相同,后跟内存区域归零。

我不明白为什么你认为malloc正在进行 lazy 分配。它没有。

好吧,有些Linux系统有memory overcommit,但你不应该依赖它(它更像是一个设计bug而不是一个功能,恕我直言)。此外,内存区域的calloc通常是通过调用mmap来实现的,这不需要额外清除该区域。

如果您需要懒惰的内容,可以将mmapMAP_NORESERVE一起使用,但要小心。

答案 4 :(得分:0)

在Linux上(也许其他操作系统也是如此 - 不确定),当你做一个malloc时,你所分配的是虚拟地址空间而不是真正的地址空间。当你去读取或写入该虚拟地址空间时,内核将找到可用的内存页面并将它们映射到该虚拟地址空间(它们可能是交换的,也可能是易失性内存)。如果你运行像htop这样的工具,它将显示一些内存统计信息。这里要看的最重要的是驻留内存和虚拟内存。驻留内存是您的进程实际拥有多少内存,虚拟内存是所请求的所有内存的总和。

因此,当您调用calloc时,它将像malloc一样分配内存。然后它会将零写入整个地址空间。这些写操作将使内核分配实际地址空间并将其映射到虚拟地址空间。

因此,考虑到这一点,malloc本身并不是懒惰而是内核是懒惰的,并且直到需要时才将内存页面分配给进程。

一般情况下,如果您需要将内存归零,则必须先使用calloc之类的内容将其全部归零,否则您需要跟踪自己将哪些内存块归零。