分配内存的问题

4
首先,我注意到当我使用malloc分配内存时,与calloc相比,内存占用量不同。我正在处理几GB的数据集。这些数据是随机的,所以可以。
我原以为只需malloc大量内存,然后读取其中的随机数据并转换为float类型即可。但是,查看进程查看器中的内存占用量时,显然没有占用内存(与calloc不同,calloc的内存占用量很大)。我运行了一个循环来将数据写入内存,然后我看到内存占用量上升了。我的问题是:在我初始化内存之前,这块内存是否实际上被占用了?
最后,在传递1024 * 1024 * 128字节(进程查看器中的1024 MB)后,我开始收到段错误。然而,Calloc似乎会初始化所有内存,直到1 GB。为什么我在使用malloc在for循环中初始化内存时,到达128MB时就会收到段错误,而内存占用量显示为1024MB?
如果我从内存中malloc一大块内存,然后从中读取数据,那我得到的是什么(因为进程查看器几乎没有显示任何内存占用量,直到我初始化它)?
最后,有没有办法让我分配超过4GB的内存?我正在测试内存层次结构的性能。
#2的代码:
    long long int i;
    long long int *test=(long long int*)malloc(1024*1024*1024);
    for (i=0;i<1024*1024*128;i++)
            test[i]=i;

    sleep(15);

3
Linux使用“乐观内存分配策略”。一些信息请参考:http://linux.die.net/man/3/malloc。 - sje397
3
“memory isn't actually claimed until I initialize it”是正确的,它是“惰性求值”的一个特例,并且由操作系统处理。然而,第二个假设,“10241024128 字节 == 1Gb”,是错误的。 - ruslik
@ruslisk - 我并没有假设1GB - 进程查看器显示1GB,我在第二个关系中询问为什么只有128MB的内存占用却是1GB。感谢您提供的信息源,这解决了一些问题。 - Joshua Enfield
2
看一下这个链接来解释你所看到的 http://opsmonkey.blogspot.com/2007/01/linux-memory-overcommit.html。它被称为内存超额配置。 - Falmarri
@Jushua:是的,它应该进行交换。根据@Falmarri的帖子,它不应该崩溃。如果你遇到了段错误,那么请检查你的程序逻辑。 - ruslik
显示剩余4条评论
4个回答

7

一些注意事项:

  1. 正如评论所指出的,Linux在您使用内存之前实际上并不分配它。
  2. 当你使用calloc而不是malloc时,它会将您请求的所有内存清零。这相当于使用它。

3

1- 如果您在32位机器上工作,则无法为一个变量分配超过2GB的空间。

2- 如果您在64位机器上工作,则可以分配总RAM + 交换内存的大小,然而,为一个变量分配所有内存需要一个大的连续内存块,这可能不可用。尝试使用链表,在其中每个元素只有1MB的分配,您可以实现更高的总内存分配。

3- 如您和Sharth所指出的那样,除非您使用内存,否则linux不会分配它。


您不必将分配的内存分成块。在32位系统上,很难找到一个大的连续地址空间,但在64位系统上这不是问题。 - ruslik

1

你的 #2 正在遭受段错误(segfault)的失败,很可能是因为 sizeof(long long int) > 8 或者是你的 malloc 函数返回了一个空指针。如果你请求了 1 GB 的内存,这种情况是非常可能发生的。

#2 的更多信息。从你的 128 MB 评论中,我得出了你可能没有意识到正在发生的事情的思路。因为你将数组指针声明为 long long int,所以每个数组元素的大小都是 8 字节。1024/8 == 128,这就是为什么你的循环可以正常工作的原因,当然,至少在我测试时是这样的。


1

你例子代码中的for循环实际上触及到1GB内存,因为它正在索引128*1024*1024个long long,每个long long占8字节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接