在C或c++应用程序中出现内存泄漏是可以接受的吗?

如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?只要内存消耗不随时间增长,那么当应用程序终止时(在Windows、Mac和Linux上),是否可以信任操作系统为您释放内存?如果内存一直被使用,直到被操作系统释放,您会认为这是真正的内存泄漏吗?

如果是第三方库将这种情况强加给您,该怎么办?会拒绝使用第三方库,不管它有多好?

我只看到了一个实际的缺点,那就是这些良性泄漏将在内存泄漏检测工具中显示为误报。


当前回答

不,你不应该有漏洞,操作系统会为你清理。原因(据我所知,在上面的答案中没有提到)是你永远不知道什么时候你的main()会在另一个程序中作为函数/模块被重用。如果你的main()在其他人的软件中经常被调用,那么这个软件就会有内存泄漏,随着时间的推移会消耗内存。

KIV

其他回答

我想以你的情况,答案可能是没关系。但是您肯定需要记录内存泄漏是一个有意识的决定。你不希望一个维护程序员出现,把你的代码放到一个函数中,然后调用它一百万次。因此,如果您决定泄漏是可以接受的,那么您需要为将来可能不得不在该程序上工作的任何人记录它(用大写字母)。

如果这是一个第三方库,你可能会被困住。但是一定要记录泄漏的发生。

但基本上,如果内存泄漏是一个已知的数量,比如512 KB的缓冲区,那么它就不是问题。如果内存泄漏持续增长,比如每次调用库调用时,内存都会增加512KB,但没有释放,那么可能有问题。如果您记录它并控制调用执行的次数,那么它可能是可管理的。但是你真的需要文档,因为虽然512不是很多,但是512超过一百万次调用就很多了。

此外,您还需要检查您的操作系统文档。如果这是一个嵌入式设备,那么操作系统可能不会从退出的程序中释放所有内存。我不确定,也许这不是真的。但这是值得研究的。

在应用程序运行后清理操作系统在概念上没有问题。

这实际上取决于应用程序以及它将如何运行。在需要运行数周的应用程序中不断发生的泄漏必须得到处理,但是一个不需要太多内存就能计算结果的小工具应该不是问题。

许多脚本语言不垃圾收集循环引用是有原因的……对于它们的使用模式,这不是一个实际的问题,因此浪费的资源和浪费的内存一样多。

是的,内存泄漏可能是两害相权取其轻。虽然正确性很重要,但在执行完全内存释放时,性能或系统的稳定性可能会受到影响,并且释放内存和销毁对象所花费的风险和时间可能比仅仅退出进程更可取。

一般来说,在周围留下内存通常是不可接受的。理解代码运行的所有作用域是很困难的,在某些情况下,这可能导致泄漏成为灾难性的。

如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?

在这种情况下,您的代码可能会移植到更大的项目中。这可能意味着您的对象的生命周期太长(它持续整个程序,而不仅仅是需要它的实例),或者如果创建并销毁全局变量,它就会泄漏。

当应用程序终止时,是否可以信任操作系统为您释放内存

当一个短生命周期的程序创建大型c++集合(例如std::map)时,每个对象至少有2个分配。对CPU来说,遍历这个集合以销毁对象需要花费实时时间,而让对象泄漏并由操作系统清理具有性能优势。计数器,有一些资源没有被操作系统整理(例如共享内存),并且不破坏代码中的所有对象会打开一些持有这些未释放资源的风险。

如果是第三方库将这种情况强加给您,该怎么办?

首先,我会为释放资源的close函数提出一个bug。是否可以接受的问题,是基于库提供的优势(成本、性能、可靠性)是否比使用其他库或自己编写更好。

一般来说,除非库可以重新初始化,否则我可能不会关心。

报告泄漏内存的可接受时间。

关闭期间的服务。这里需要在时间性能和正确性之间进行权衡。 一个破碎的无法被摧毁的物体。我已经能够检测到一个失败的对象(例如,由于异常被捕获),当我尝试并销毁对象时,结果是挂起(持有锁)。 内存检查错误报告。

关闭期间的服务

如果操作系统即将关闭,所有资源将被清理。不执行正常进程关闭的优点是,用户在关闭时可以获得更快的性能。

破损的物品

在我的过去,我们发现了一个对象(并为该团队提出了一个缺陷),如果它们在某些点崩溃,它们就会被破坏,该对象中的所有后续函数都会导致挂起。

尽管忽略内存泄漏是一种糟糕的做法,但关闭进程、泄漏对象及其内存比导致挂起更有效。

泄漏检查错误报告

一些泄漏检查器通过检测对象来工作,并以与全局变量相同的方式工作。它们有时会忽略另一个全局对象有一个有效的析构函数,在它们完成后调用,这将释放内存。

我相信有人能想出一个理由说“是”,但不会是我。 与其说“不”,我要说的是,这不应该是一个“是”或“否”的问题。 有许多方法可以管理或控制内存泄漏,许多系统都有内存泄漏。

在离开地球的设备上有NASA的系统为这个做了计划。系统会经常自动重启,这样内存泄漏就不会对整体操作造成致命影响。这只是一个遏制的例子。

也许是在细枝末节:如果您的应用程序运行在UNIX上,可能会变成僵尸怎么办?在这种情况下,内存不会被操作系统回收。所以我说你应该在程序退出之前重新分配内存。