如果内存占用不是问题,对于一个短暂的程序,我是否应该释放内存?

4
我有一个程序,会执行以下操作:
  1. 分配内存(堆)
  2. 进行一些处理
  3. 再次分配内存(堆)
  4. 进行一些处理
程序会重复执行上述操作几次,然后退出。
我并不关心程序的内存占用情况,只关注执行时间。
如果不释放内存,是否会有问题呢?因为释放内存可能比跳过并继续下一步骤更耗时。
最终,程序将退出,这就不再重要了。
我知道唯一确定的方法是在计算机上进行一些基准测试,但我对理论上的优缺点很感兴趣。
注:假设使用现代操作系统,在退出时会清理内存。

4
这个问题真的很难回答,有时候free()会节省时间。 - Stargateur
1
在这种情况下,你最好使用全局作用域的缓冲区/结构。这取决于你的使用情况以及你是否事先知道你的最大需求是什么。如果你正在使用C++,你应该使用RAII,所以要么你错误地标记了它,要么你应该真正了解一下RAII是什么。 - kamikaze
2
@Stargateur,你能举个例子吗?(出于好奇) - Kami Kaze
3
假设调用 free 释放了一个内存块,这个内存块可以让下一次调用 malloc 更快地找到一个合适的块。因此,摊销时间会更好。 - StoryTeller - Unslander Monica
1
@Antzi 如果你使用 free,未来的 malloc 可能会重复使用先前 malloc 的内存。这可以节省时间,因为旧内存不必从操作系统中获取,并且很可能已经在缓存中。页面错误和缓存未命中可能会使事情变得相当慢。 - Petr Skocik
显示剩余8条评论
5个回答

3
释放已分配的内存是否会带来性能优劣取决于您的分配模式和内存使用方式。如果您使用free释放内存,则未来的 malloc 可能会重复使用之前的内存,这可以节省时间,因为旧内存不必从操作系统中获取,且可能已经在高速缓存中。页面故障和缓存未命中可能会明显减慢程序运行速度。
如果您关心这一点,请对您的程序进行释放和不释放内存的基准测试。

就像你为我所做的那样:https://dev59.com/j57ha4cB1Zd3GeqPlI97#41870241 - Kami Kaze

3

有许多潜在问题。例如:

  • 如果你事先无法预测实际需要多少内存 - 这是使用动态内存分配的最常见原因之一 - 那么你的程序可能会耗尽可用内存(由于耗尽系统内存或主机操作系统对程序施加配额)。此后,它可能会以所需速度运行,也可能不会,但即使忽略时间问题,它也很可能运行不正确并产生错误的结果。无论你的主机系统有多少内存,或者主机系统为其托管的程序强制执行什么配额 - 都有可能耗尽该金额。
  • 并非所有操作系统都会在程序退出时释放内存。在那些这样做的操作系统中,有可能内存没有完全释放 - 这既是由于操作系统本身的错误,也是由于你的程序的操作(例如分配与其他程序共享的资源)造成的。在这种情况下,如果你的程序运行了多次,你可能会发现程序(在第32次运行时[随机选择一个数字]左右)会莫名其妙地失败。
  • 随着程序分配更多的内存,取决于如何管理动态内存分配(例如malloc()使用的数据结构),如果不释放内存,分配本身就会变慢。这可能会导致你的程序在分配更多内存时无法满足时间约束。释放不再需要的内存可以缓解这些问题(尽管会有其他影响,例如内存碎片化)。
  • 如果你养成了不释放动态分配内存的习惯,由于“效率”原因,你可能也不会费心检查分配是否成功 - 毕竟那也需要时间。如果分配失败,这会导致问题(例如异常程序终止、崩溃内存、在没有警告的情况下产生错误结果等)。

总之,如果你关心程序性能或时间,分配内存而不释放它是一种非常糟糕(和懒惰)的策略。如果你真的关心程序性能/时间,你实际上根本不会动态分配内存。

如果你正在使用动态内存分配,则最好在不再需要时释放它,即使你不关心内存占用。根据情况,如果你正确释放内存,你可能会发现程序运行得更快或更慢(这取决于许多变量,包括我上面提到的以及更多)。并且,如果你的代码没有正确释放内存,那么当你需要在更大的程序中重复使用代码时 - 在实际情况下,这种情况比不重复使用代码更常见 - 你更有可能遇到问题(内存问题、性能问题)。


1
你将内存分配在哪里?堆还是栈?对于你的情况,我建议你在栈上分配(即不使用任何内存分配函数)。
然而,大多数操作系统在程序退出时会释放你在堆中所占用的空间。 如果你正在使用堆,并且你正在使用现代C++编码,你需要阅读智能指针
创建栈对象具有最低的性能损失,并且它们是基于范围的(这甚至更酷)。唯一的缺点是空间非常有限。
另一种技术是最初在堆上预先分配一块内存块;并管理已分配的空间以供使用,这在模拟器中很常见。

堆。智能指针很好用,但与使用free/delete相同。 - Antzi
不,它们是不同的。1. 它们可以节省您的开发时间,2. 只有在作用域外时才会发生删除。 - Gamma.X
此外,您应该小心处理内存分配。最终,当您过度分配内存时,您的程序将变慢,整个系统也会受到影响。为了避免因不使用free方法而导致的初始优化被破坏,您应该删除未使用的内存。 - Gamma.X

0

这主要取决于程序运行的位置,大多数现代操作系统会在退出时清除程序分配的内存。因此,只要您不分配大量内存,就不应该有问题。

但是,如果您在嵌入式系统中工作,则可能不是这样。

编辑:如果操作系统在执行后清除内存,则唯一的问题可能是您分配的内存超过了可用内存。但只要不发生这种情况,我认为就没有问题。这是现今某些程序的常见做法。


我澄清了问题:假设内存已被操作系统清理。 - Antzi

0

出于几个原因,程序终止前应始终释放所有已分配的内存。

  1. 这通常被认为是最佳实践。
  2. 不清楚让运行时在您之后清理是否有任何好处(以执行速度为衡量标准)。
  3. 这可以避免内存泄漏,以防运行时环境未能收集所有内存。
  4. 如果您曾经扩展过此程序或在其基础上构建过其他代码,则可能会导致内存泄漏蔓延到其他代码中。

此外,在C++中,您应该避免需要“手动”内存释放,并依赖于RAII方法,例如通过其容器和智能指针提供的标准库。


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