使用动态数组时,内存使用在for循环中不断增加。(C ++)

时间:2016-04-29 05:43:52

标签: c++ arrays

以下是我的C ++代码。

如果我尝试使用test1数组来计算任何内容,我发现内存使用会不断增加。

double **test1;
test1=new double *[1000];

for(int i=0;i<1000;i++){
    test1[i]=new double [100000000];
    test1[i][0]=rand() / (double)RAND_MAX*100;
}

for(int j=1;j<100000000;j++){
    for(int i=0;i<1000;i++){
        test1[i][j]=test1[i][j-1];  //this cause memory use increase.
    }
}

如果删除该行。

test1[i][j]=test1[i][j-1];

内存使用将成为一个小的常量值。

我以为我已经在第一部分声明了动态数组,如果我没有新的任何数组,内存使用应该是常量。

内存使用增加的原因是什么?我该如何避免呢?

(我使用linux命令“top”来监视内存使用情况。)

2 个答案:

答案 0 :(得分:4)

在第一个循环中,您创建100,000,000个双精度,即800 MB的分配。你只写第一个。

稍后你会写信给其他人。当你这样做时,操作系统实际上需要给你内存写入,而最初它只是给你一个映射,以便稍后(当你写它时)页面错误。

基本上,由于每次分配都很大,所以支持它所需的内存在使用之前不会进行物理分配。

代码是荒谬的,因为最终你会尝试写入800 GB的内存。我怀疑这将在一台典型的计算机上完成。

答案 1 :(得分:2)

在虚拟内存系统上,Linux内核(默认情况下)在程序进行分配时不会实际分配任何物理内存。相反,它只会调整您的虚拟地址空间大小。 想想它就像内核一样......嗯,是的,你说你想要这么多的记忆。我记得我答应过你,但是在我去为你取得它之前,让我们看看你是否真的要使用它了#34;。 如果你实际上去写入内存,内核将获得实际内存实际上不支持的虚拟地址的页面错误,此时它将分配一些实际内存来支持你写入的页面

许多程序永远不会写入它们分配的所有内存,因此只要实现承诺,内核就会节省大量内存。

您可以在ps aux的输出中查看已分配的金额与实际占用实际内存量的金额之间的差异,即查看VSS(虚拟集大小)和RSS(驻留集大小)列

如果您希望所有分配始终由物理内存支持(您可能没有),那么您可以通过vm.overcommit_memory sysctl开关更改内核过度使用策略。