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

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

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

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


当前回答

我完全同意JohnMcG的观点,只是想补充一点,我自己也有问题,无法及时发现真实的、潜在的严重内存泄漏,只是因为人们已经接受了良性的内存泄漏。随着时间的推移,这些病毒变得如此之多,在大量的良性病毒中发现严重病毒就变得越来越困难。

因此,至少为了你的程序员同事(也是为了你自己的未来),请尽快消除它们。

其他回答

我同意vfilby -这要看情况。在Windows中,我们将内存泄漏视为相对严重的错误。但是,这很大程度上取决于分量。

例如,对于很少运行且运行时间有限的组件,内存泄漏不是很严重。这些组件运行,完成工作,然后退出。当它们退出时,所有内存都被隐式释放。

但是,服务或其他长期运行组件(如shell)中的内存泄漏非常严重。原因是这些bug会随着时间的推移“窃取”内存。恢复的唯一方法是重新启动组件。大多数人不知道如何重新启动服务或shell——所以如果他们的系统性能受到影响,他们就重新启动。

所以,如果你有一个泄漏-评估它的影响两种方式

你的软件和你的用户体验。 对于系统(和用户)来说,节省系统资源是非常重要的。 修复对维护和可靠性的影响。 在其他地方造成倒退的可能性。

前甲板

只要您的内存利用率不随着时间的推移而增加,这取决于情况。如果你在服务器软件中做很多复杂的同步,比如启动阻塞系统调用的后台线程,那么完全关闭可能太复杂了。在这种情况下,备选方案可能是:

直到进程退出才清理内存的库。 您编写了额外的500行代码,并向类中添加了另一个互斥量和条件变量,以便它可以从测试中干净地关闭—但是这些代码从未在生产中使用,在生产中服务器只会因崩溃而终止。

这个问题已经讨论得令人作呕了。最重要的是,内存泄漏是一个bug,必须修复。如果第三方库泄露了内存,就会让人怀疑它还有什么问题,不是吗?如果你要造一辆汽车,你会使用一个偶尔漏油的发动机吗?毕竟,引擎是别人做的,所以这不是你的错,你不能修,对吧?

在这类问题中,语境就是一切。就我个人而言,我不能忍受漏洞,在我的代码中,如果它们突然出现,我就会竭尽全力去修复它们,但修复漏洞并不总是值得的,当人们按小时支付我的报酬时,我有时会告诉他们,我的费用不值得我修复他们代码中的漏洞。让我给你们举个例子:

I was triaging a project, doing some perf work and fixing a lot of bugs. There was a leak during the applications initialization that I tracked down, and fully understood. Fixing it properly would have required a day or so refactoring a piece of otherwise functional code. I could have done something hacky (like stuffing the value into a global and grabbing it some point I know it was no longer in use to free), but that would have just caused more confusion to the next guy who had to touch the code.

就我个人而言,我一开始就不会以这种方式编写代码,但我们大多数人并不总是在设计良好的原始代码库上工作,有时你必须务实地看待这些事情。修复150字节泄漏所花费的时间可以用来改进算法,从而减少兆字节的内存。

最终,我决定为一个使用大约1g内存并运行在专用机器上的应用程序泄露150个字节不值得修复,所以我写了一条评论说它被泄露了,为了修复它需要改变什么,以及为什么当时不值得。

不,它们不是可以的,但是我已经实现了一些分配器、内存转储器和泄漏检测器,并且发现从实用的角度来看,允许人们将这样的分配标记为“就泄漏报告而言,不是泄漏”是很方便的……

这有助于使泄漏报告更有用……不要充斥着“静态范围内的动态分配不被程序退出释放”