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

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

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

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


当前回答

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

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

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

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

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

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

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

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

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

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

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

关闭期间的服务

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

破损的物品

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

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

泄漏检查错误报告

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

其他回答

即使您确定“已知的”内存泄漏不会造成严重破坏,也不要这样做。在最好的情况下,它会为你在不同的时间和地点犯下类似的、可能更严重的错误铺平道路。

对我来说,问这个问题就像问“我可以在凌晨3点没有人的时候闯红灯吗?”当然,在那个时候它可能不会造成任何麻烦,但它将为你在高峰时间做同样的事情提供一个杠杆!

我的回答是没有。

从理论上讲,如果你把东西弄得乱七八糟,操作系统会帮你清理干净(这很粗鲁,但由于计算机没有感情,这可能是可以接受的)。但是,您无法预测程序运行时可能发生的每一种情况。因此(除非您能够对某些行为进行正式的证明),从专业的角度来看,造成内存泄漏是不负责任和草率的。

如果第三方组件泄漏内存,这是一个非常强烈的反对使用它的理由,不仅因为即将发生的影响,而且因为它表明程序员工作草率,这也可能影响其他指标。现在,当考虑遗留系统时,这是困难的(考虑web浏览组件:据我所知,它们都泄漏内存),但这应该是标准。

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

我很惊讶看到这么多关于内存泄漏的错误定义。如果没有一个具体的定义,关于它是否是坏事的讨论就不会有任何结果。

正如一些评论员正确地指出的那样,只有当进程分配的内存超出作用域,以至于该进程不再能够引用或删除它时,才会发生内存泄漏。

A process which is grabbing more and more memory is not necessarily leaking. So long as it is able to reference and deallocate that memory, then it remains under the explicit control of the process and has not leaked. The process may well be badly designed, especially in the context of a system where memory is limited, but this is not the same as a leak. Conversely, losing scope of, say, a 32 byte buffer is still a leak, even though the amount of memory leaked is small. If you think this is insignificant, wait until someone wraps an algorithm around your library call and calls it 10,000 times.

我认为没有任何理由允许在您自己的代码中泄漏,无论多么小。现代编程语言,如C和c++,不遗余力地帮助程序员防止此类泄漏,并且很少有好的理由不采用好的编程技术——特别是在与特定的语言功能相结合时——来防止泄漏。

对于现有的或第三方代码,您对质量的控制或进行更改的能力可能非常有限,这取决于泄漏的严重程度,您可能被迫接受或采取缓解措施,例如定期重新启动进程以减少泄漏的影响。

更改或替换现有的(泄漏的)代码可能是不可能的,因此您可能不得不接受它。然而,这并不等同于宣称它是OK的。

除非“使用”的内存量不断增长,否则我不认为这是内存泄漏。有一些未释放的内存,虽然不是理想的,但不是一个大问题,除非所需的内存数量不断增长。