繁体   English   中英

memory 泄漏 go 能走多远?

[英]How far can memory leaks go?

我多次遇到 memory 泄漏。 通常当我是malloc时 - 就像没有明天一样,或者像脏衣服一样悬空FILE * s。 我通常假设(阅读:绝望地希望)至少在程序终止时所有 memory 都被清理了。 是否存在程序终止或崩溃时无法收集泄漏的 memory 的情况?

如果答案因语言而异,那么让我们关注 C(++)。

请注意短语的双曲用法,“就像没有明天”和“晃来晃去……像脏衣服一样”。 不安全* malloc *ing 会伤害您所爱的人。 此外,请谨慎使用脏衣服。

否。操作系统在进程退出时释放进程持有的所有资源。

这适用于操作系统维护的所有资源:内存,打开文件,网络连接,窗口句柄......

也就是说,如果程序在没有操作系统的嵌入式系统上运行,或者在操作系统非常简单或有缺陷的情况下运行,则在重新启动之前内存可能无法使用。 但如果你处于那种情况,你可能不会问这个问题。

操作系统可能需要很长时间才能释放某些资源。 例如,即使程序正确关闭,网络服务器用于接受连接的TCP端口也可能需要几分钟才能获得空闲。 联网程序还可以保存远程资源,例如数据库对象。 当网络连接丢失时,远程系统应释放这些资源,但可能需要比本地操作系统更长的时间。

C标准没有规定当程序终止时释放malloc分配的malloc 这由操作系统完成,而不是所有操作系统(通常这些都在嵌入式世界中)在程序终止时释放内存。

由于所有答案都涵盖了现代操作系统中问题的大多数方面,但从历史上看,如果您曾在DOS世界中编程,那么还有一个值得一提。 终止和驻留 (TSR)程序通常会将控制权返回给系统,但会驻留在可由软件/硬件中断恢复的内存中。 在处理这些操作系统时,看到“内存不足!尝试卸载某些TSR”这样的消息是正常的。

因此从技术上讲, 程序会终止 ,但由于它仍然驻留在内存中,因此除非卸载程序,否则不会释放任何内存泄漏。

因此,您可以将此视为另一种情况,除了操作系统不回收内存,因为它有问题,或者因为嵌入式操作系统是为此而设计的。

我记得还有一个例子。 客户信息控制系统 (CICS)是一种主要在IBM大型机上运行的事务服务器,它是伪对话的。 执行时,它处理用户输入的数据,为用户生成另一组数据,传输到用户终端节点并终止。 在激活注意键时,它再次恢复以处理另一组数据。 由于它的行为方式,从技术上讲,操作系统不会从已终止的CICS程序中回收内存,除非您回收CICS事务服务器。

与其他人所说的一样,大多数操作系统将在进程终止时回收已分配的内存(可能还有其他资源,如网络套接字,文件句柄等)。

话虽如此,在处理new / delete(而不是raw malloc / free)时,内存可能不是你唯一需要担心的事情。 在new中分配的内存可能会被回收,但是可能在对象的析构函数中完成的事情不会发生。 也许某个类的析构函数在销毁时将一个sentinel值写入文件中。 如果进程刚刚终止,则可以刷新文件句柄并回收内存,但不会写入该sentinel值。

故事的道德,总是清理自己。 不要让事情摇摇欲坠。 在你之后不要依赖操作系统清理。 自己清理干净。

这更可能取决于操作系统而非语言。 最终,任何语言的任何程序都将从操作系统中获取内存。

我从来没有听说过程序退出/崩溃时没有回收内存的操作系统。 因此,如果你的程序在它需要分配的内存上有一个上限,那么分配和永不释放是完全合理的。

所有值得拥有标题的操作系统都会清理您终止后的过程。 但是总会有无法预料的事件,如果它以某种方式被拒绝访问并且一些可怜的程序员没有预见到这种可能性会怎么样,所以它不会再稍后再尝试呢? 如果内存泄漏是关键任务,那么总是更安全地清理自己 - 否则,如果这种努力代价高昂,那么IMO的努力就不值得。

编辑:如果内存泄漏存在于积聚的位置(如循环中),则需要清除内存泄漏。 我所说的内存泄漏是在整个程序过程中不断积累的内存泄漏,如果你有任何其他类型的泄漏,它很可能迟早会成为一个严重的问题。

在技​​术方面,如果你的泄漏是内存“复杂性”O(1)它们在大多数情况下都很好,O(logn)已经令人不愉快(在某些情况下是致命的)和O(N)+无法忍受。

如果程序变成一个加载到另一个程序的地址空间的动态组件(“插件”),即使在具有整洁内存管理的操作系统上也会很麻烦。 我们甚至不必考虑将代码移植到功能较弱的系统。

另一方面,释放所有内存可能会影响程序清理的性能。

我正在研究的一个程序,某个测试用例需要30秒或更长时间才能退出程序,因为它通过所有动态内存的图形递归并逐个发布。

一个合理的解决方案是在那里具有该功能并用测试用例覆盖它,但是在生产代码中将其关闭以便应用程序快速退出。

POSIX兼容系统上的共享内存将持续存在,直到调用shm_unlink或重新引导系统。

如果您有进程间通信,这可能导致其他进程永远不会完成并消耗资源,具体取决于协议。

举个例子,当我在打印机作业中终止JVM时,我曾尝试用Java打印到PDF打印机,PDF假脱机过程仍然有效,我不得不在任务管理器中将其杀死重试打印。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM