在C或c++应用程序中出现内存泄漏是可以接受的吗?
如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?只要内存消耗不随时间增长,那么当应用程序终止时(在Windows、Mac和Linux上),是否可以信任操作系统为您释放内存?如果内存一直被使用,直到被操作系统释放,您会认为这是真正的内存泄漏吗?
如果是第三方库将这种情况强加给您,该怎么办?会拒绝使用第三方库,不管它有多好?
我只看到了一个实际的缺点,那就是这些良性泄漏将在内存泄漏检测工具中显示为误报。
是的,内存泄漏可能是两害相权取其轻。虽然正确性很重要,但在执行完全内存释放时,性能或系统的稳定性可能会受到影响,并且释放内存和销毁对象所花费的风险和时间可能比仅仅退出进程更可取。
一般来说,在周围留下内存通常是不可接受的。理解代码运行的所有作用域是很困难的,在某些情况下,这可能导致泄漏成为灾难性的。
如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?
在这种情况下,您的代码可能会移植到更大的项目中。这可能意味着您的对象的生命周期太长(它持续整个程序,而不仅仅是需要它的实例),或者如果创建并销毁全局变量,它就会泄漏。
当应用程序终止时,是否可以信任操作系统为您释放内存
当一个短生命周期的程序创建大型c++集合(例如std::map)时,每个对象至少有2个分配。对CPU来说,遍历这个集合以销毁对象需要花费实时时间,而让对象泄漏并由操作系统清理具有性能优势。计数器,有一些资源没有被操作系统整理(例如共享内存),并且不破坏代码中的所有对象会打开一些持有这些未释放资源的风险。
如果是第三方库将这种情况强加给您,该怎么办?
首先,我会为释放资源的close函数提出一个bug。是否可以接受的问题,是基于库提供的优势(成本、性能、可靠性)是否比使用其他库或自己编写更好。
一般来说,除非库可以重新初始化,否则我可能不会关心。
报告泄漏内存的可接受时间。
关闭期间的服务。这里需要在时间性能和正确性之间进行权衡。
一个破碎的无法被摧毁的物体。我已经能够检测到一个失败的对象(例如,由于异常被捕获),当我尝试并销毁对象时,结果是挂起(持有锁)。
内存检查错误报告。
关闭期间的服务
如果操作系统即将关闭,所有资源将被清理。不执行正常进程关闭的优点是,用户在关闭时可以获得更快的性能。
破损的物品
在我的过去,我们发现了一个对象(并为该团队提出了一个缺陷),如果它们在某些点崩溃,它们就会被破坏,该对象中的所有后续函数都会导致挂起。
尽管忽略内存泄漏是一种糟糕的做法,但关闭进程、泄漏对象及其内存比导致挂起更有效。
泄漏检查错误报告
一些泄漏检查器通过检测对象来工作,并以与全局变量相同的方式工作。它们有时会忽略另一个全局对象有一个有效的析构函数,在它们完成后调用,这将释放内存。
一般情况下,如果遇到无法避免的内存泄漏,则需要更加认真地考虑对象所有权问题。
但对于你的问题,我的回答是在产品代码中,是的。在开发过程中,没有。这听起来可能有些倒退,但我的理由是:
In the situation you describe, where the memory is held until the end of the program, it's perfectly okay to not release it. Once your process exits, the OS will clean up anyway. In fact, it might make the user's experience better: In a game I've worked on, the programmers thought it would be cleaner to free all the memory before exiting, causing the shutdown of the program to take up to half a minute! A quick change that just called exit() instead made the process disappear immediately, and put the user back to the desktop where he wanted to be.
但是,您对调试工具的看法是正确的:它们会突然发作,而且所有的假阳性可能会使查找真正的内存泄漏变得很痛苦。正因为如此,总是编写释放内存的调试代码,并在发布时禁用它。