在C或c++应用程序中出现内存泄漏是可以接受的吗?
如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?只要内存消耗不随时间增长,那么当应用程序终止时(在Windows、Mac和Linux上),是否可以信任操作系统为您释放内存?如果内存一直被使用,直到被操作系统释放,您会认为这是真正的内存泄漏吗?
如果是第三方库将这种情况强加给您,该怎么办?会拒绝使用第三方库,不管它有多好?
我只看到了一个实际的缺点,那就是这些良性泄漏将在内存泄漏检测工具中显示为误报。
从历史上看,在某些边缘情况下,它在某些操作系统上确实很重要。这些边缘情况在未来可能会存在。
Here's an example, on SunOS in the Sun 3 era, there was an issue if a process used exec (or more traditionally fork and then exec), the subsequent new process would inherit the same memory footprint as the parent and it could not be shrunk. If a parent process allocated 1/2 gig of memory and didn't free it before calling exec, the child process would start using that same 1/2 gig (even though it wasn't allocated). This behavior was best exhibited by SunTools (their default windowing system), which was a memory hog. Every app that it spawned was created via fork/exec and inherited SunTools footprint, quickly filling up swap space.
一般情况下,如果遇到无法避免的内存泄漏,则需要更加认真地考虑对象所有权问题。
但对于你的问题,我的回答是在产品代码中,是的。在开发过程中,没有。这听起来可能有些倒退,但我的理由是:
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.
但是,您对调试工具的看法是正确的:它们会突然发作,而且所有的假阳性可能会使查找真正的内存泄漏变得很痛苦。正因为如此,总是编写释放内存的调试代码,并在发布时禁用它。
在这类问题中,语境就是一切。就我个人而言,我不能忍受漏洞,在我的代码中,如果它们突然出现,我就会竭尽全力去修复它们,但修复漏洞并不总是值得的,当人们按小时支付我的报酬时,我有时会告诉他们,我的费用不值得我修复他们代码中的漏洞。让我给你们举个例子:
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个字节不值得修复,所以我写了一条评论说它被泄露了,为了修复它需要改变什么,以及为什么当时不值得。