你认为不为小程序释放内存是个好主意吗?

Met*_*est -5 c c++ linux

让我们说我的系统有4GB的RAM,某个程序在执行过程中只消耗100 MB的内存,并且运行时间有限,只有30秒.难道你不认为在执行该程序期间根本不释放内存是一个好主意(通过提高性能)吗?无论如何,在该程序终止时,这些100 MB将被释放.

Ste*_*Cox 7

在短期运行的程序中释放内存最重要的部分是精简内存重用.您的处理器具有有限的缓存,可能只有几MB,如果您不断分配更多内存,则永远无法利用它.

但是,如果您释放一些内存,然后重新分配并重新使用它,则很有可能在重用时内存已经"热"并驻留在缓存中.这意味着您不会因缓存未命中而受到惩罚,并且您的程序将运行得更快.

当然,您要考虑缓存未命中的重新分配/重新分配成本,但是不断分配越来越多的内存可以保证产生最低级别的缓存未命中.这些高速缓存未命中中的每一个在现代处理器上花费大约100个指令,小于分配/解除分配的成本.

编辑

所以我做了一个小测试程序来测试这个.

#include <stdio.h>
#include <stdlib.h>

process1(){
    char * ptr = malloc(1 << 20);
    int i = 0;
    while (i < (1<<20)) ptr[i++] = rand();
    free(ptr);
}

process2(){
    char * ptr = malloc(1 << 20);
    int i = 0;
    while (i < (1<<20)) ptr[i++] = rand();
}


main(){
    int i = 100;
    while(i--) process1();
    i = 100;
    while(i--) process2();
}
Run Code Online (Sandbox Code Playgroud)

这两个进程都会通过100 MB的数据进行咀嚼,第一个进程将其解除分配,第二个进程不会.我用valgrind的cachegrind工具对此进行了分析.结果如下

fn=process1
0 943720200 2 2 419430900 100 0 209715800 1638400 32767
fn=process2
0 943719900 0 0 419430800 100 0 209715700 1638400 1605784
Run Code Online (Sandbox Code Playgroud)

好吧不是那么令人兴奋,我会翻译.通过避免释放,您节省了不到0.1%的指令周期,并且您导致大约一百五十个LL缓存未命中.如果我们使用标准循环估计公式CEst = lr + 10 Llm + 100 LLm,其性能降低约16%,从而避免单独使用该函数.

我重新调用callgrind来获取完整的故事(我不会发布详细的结果,因为它们比缓存研究更复杂)但是当我们将完整的调用包含在free中时,结果是相同的,增加了16%不拨打免费电话时使用周期.

您可以随意在自己的程序中进行相同的测试,但在这种情况下,结果很清楚.与使用新内存不断刷新缓存的成本相比,管理动态内存的成本确实微不足道.

此外,我没有提到这一点,但应该进行的直接比较是免费的成本,以及缓存未命中的成本.免费总共花费38930个周期,缓存未命中157332000,您节省了39000个周期,并为其支付了1.5亿个.


Par*_*hot 6

Don't you think its a good idea not to deallocate memory at all during the execution of that program?

偷工减料并不是一个"好主意".我可以想出释放记忆的充分理由; 我想不出那么多未分配未使用的内存.如果您不想处理内存问题,请不要使用没有自动垃圾收集的语言编写 - 或者,因为您使用C++编写,请使用智能指针.

only consumes 100 MB of memory

这是我所见过的"唯一"这个词最令人震惊的滥用.100 MB是一个重要的变化.这是你正在使用的内存的1/40,如果在系统上运行的其他40个程序都使用相同的视角进行编程,那么最好让系统由于交换延迟而停止运行,并且最糟糕的是你有一个完整的系统崩溃.通常,在任何给定(现代)机器上运行时,有40多个应用程序在运行时运行.

also runs for a limited time, like only 30 seconds

同样,对于计算机来说,30秒是很长的时间.但是,为了澄清,你的意思是30秒以往的每一天,或30秒?因为如果它是一次性的而且你的时间很短,也许这是一个可以接受的损失,但它肯定不是好的做法.

TL; DR?

如果您有更重要的,即时的考虑因素(例如产品截止日期临近),而您没有其他合理的选择,那就去做吧.否则,你没有任何借口.慢跑记忆绝不是你应该感觉良好的东西; 它会严重减慢,真正的过程需要的内存.是的,O/S在程序结束后清理资源.不,这并不能让您全权编写滥用其资源的程序.