当前位置:  开发笔记 > 编程语言 > 正文

有些分配器是懒惰的吗?

如何解决《有些分配器是懒惰的吗?》经验,为你挑选了2个好方法。

我在Linux中编写了一个C语言程序,用于mallocs内存,在循环中运行它,而TOP没有显示任何内存消耗.

然后我用那个记忆做了一些事情,TOP确实显示了内存消耗.

当我在malloc时,我真的"得到了内存",还是有一个"懒惰"的内存管理,只有在我使用它时才给我内存?

(还有一个选项,当我使用它时TOP才知道内存消耗,所以我不确定这个...)

谢谢



1> bdonlan..:

在Linux上,malloc使用sbrk()或mmap()请求内存 - 无论哪种方式,您的地址空间都会立即扩展,但Linux在第一次写入相关页面之前不会分配实际的物理内存页面.您可以在VIRT列中看到地址空间扩展,而在RES中可以看到实际的物理内存使用情况.



2> Robert S. Ba..:

这从主题开始(然后我将其与您的问题联系在一起),但是发生的事情类似于在Linux中派生一个进程时发生的事情。派生时,有一种称为写时复制的机制,该机制也仅在写入内存时才为新进程复制内存空间。这样,如果分叉的流程执行程序立即是一个新程序,那么您就节省了复制原始程序内存的开销。

回到您的问题,这个想法是相似的。正如其他人指出的那样,请求内存会立即为您提供虚拟内存空间,但是实际页面仅在写入它们时才分配。

目的是什么?它基本上使对内存的分配成为一个或多或少的固定时间操作Big O(1)而不是Big O(n)操作(类似于linux调度程序的工作方式,而不是大块地进行)。

为了证明我的意思,我做了以下实验:

rbarnes@rbarnes-desktop:~/test_code$ time ./bigmalloc 

real    0m0.005s
user    0m0.000s
sys 0m0.004s
rbarnes@rbarnes-desktop:~/test_code$ time ./deadbeef 

real    0m0.558s
user    0m0.000s
sys 0m0.492s
rbarnes@rbarnes-desktop:~/test_code$ time ./justwrites 

real    0m0.006s
user    0m0.000s
sys 0m0.008s

bigmalloc程序分配2000万个整数,但不对其进行任何处理。deadbeef向每个页面写入一个int,导致19531次写入,justwrites分配19531个int,然后将它们清零。如您所见,deadbeef的执行时间比bigmalloc长100倍,比justwrites长约50倍。

#include     

int main(int argc, char **argv) {

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes

return 0;

}

#include     

int main(int argc, char **argv) {

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes

// immediately write to each page to simulate all at once allocation

// assuming 4k page size on 32bit machine

for ( int* end = big + 20000000; big < end; big+=1024 ) *big = 0xDEADBEEF ;    

return 0;

}

#include 

int main(int argc, char **argv) {

int *big = calloc(sizeof(int),19531); // number of writes

return 0;
}

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有