我已经多次遇到内存泄漏。通常,当我- malloc
希望没有明天,或者FILE *
像脏衣服一样晃来晃去时。我通常认为(拼命:希望)至少在程序终止时才清理所有内存。在程序终止或崩溃时,是否存在无法收集泄漏内存的情况?
如果答案因语言而异,那么让我们关注C(++)。
请注意,短语“好像没有明天”和“晃来晃去……就像脏衣服”一样是双曲线的用法。不安全* malloc
可能伤害您所爱的人。另外,请注意不要弄脏衣物。
calloc
没有明天。优秀的。
我已经多次遇到内存泄漏。通常,当我- malloc
希望没有明天,或者FILE *
像脏衣服一样晃来晃去时。我通常认为(拼命:希望)至少在程序终止时才清理所有内存。在程序终止或崩溃时,是否存在无法收集泄漏内存的情况?
如果答案因语言而异,那么让我们关注C(++)。
请注意,短语“好像没有明天”和“晃来晃去……就像脏衣服”一样是双曲线的用法。不安全* malloc
可能伤害您所爱的人。另外,请注意不要弄脏衣物。
calloc
没有明天。优秀的。
Answers:
否。操作系统在退出时会释放进程所拥有的所有资源。
这适用于操作系统维护的所有资源:内存,打开的文件,网络连接,窗口句柄...
也就是说,如果程序在没有操作系统的嵌入式系统上运行,或者在非常简单或错误的操作系统上运行,则在重新启动之前,内存可能无法使用。但是,如果您处在这种情况下,您可能不会问这个问题。
操作系统可能需要很长时间才能释放某些资源。例如,即使程序已正确关闭,网络服务器用来接受连接的TCP端口也可能需要几分钟才能释放。联网程序还可以保存远程资源,例如数据库对象。当网络连接丢失时,远程系统应释放这些资源,但是它可能比本地操作系统花费更长的时间。
ipcrm
进行手动清理的原因,linux.die.net/man/8/ipcrm。
C标准未指定malloc
在程序终止时释放由分配的内存。这是由操作系统完成的,并不是所有的OS(通常在嵌入式世界中)都会在程序终止时释放内存。
main
返回时,malloc
释放由分配的所有内存。例如,它说所有打开的文件在程序终止前都已关闭。对于分配了my的内存malloc
,只是未指定。当然,现在我关于操作系统的一句话描述的是标准所规定的通常没有做的事情,因为它没有对此做任何规定。
std::atexit
还考虑通过终止程序std::exit
,然后还有std::abort
和(特定于C ++)std::terminate
。
atexit
将无法使用。:-)
由于所有答案都涵盖了现代OS的大部分问题,但是从历史上看,如果您曾经在DOS世界中编程过,那么值得一提的是。终止驻留程序(TSR)通常会将控制权返回给系统,但驻留在内存中,可以通过软件/硬件中断来恢复。在这些操作系统上工作时,通常会看到诸如“内存不足!尝试卸载某些TSR”之类的消息。
因此,从技术上讲,该程序将终止,但由于它仍驻留在内存中,因此除非您卸载该程序,否则不会释放任何内存泄漏。
因此,您可以考虑这是另一种情况,除了操作系统由于存在故障或嵌入式OS旨在回收内存而没有回收内存。
我还记得一个例子。 客户信息控制系统(CICS)是主要在IBM大型机上运行的事务服务器,它是伪会话。在执行时,它处理用户输入的数据,为用户生成另一组数据,传输到用户终端节点并终止。激活注意键后,它会再次恢复以处理另一组数据。因为它的行为方式,从技术上来说,再次是,操作系统不会从终止的CICS程序中回收内存,除非您回收CICS事务服务器。
就像其他人所说的那样,大多数操作系统将在进程终止时回收分配的内存(可能还会回收其他资源,例如网络套接字,文件句柄等)。
话虽如此,在处理new / delete(而不是raw malloc / free)时,内存可能并不是您唯一需要担心的事情。可以回收用new分配的内存,但是不会在对象的析构函数中完成任何事情。也许某个类的析构函数在销毁时将标记值写入文件中。如果该过程刚刚终止,则可能会刷新文件句柄并回收内存,但不会写入哨兵值。
故事的寓意,总是要自己清理。不要让事情悬而未决。在您执行完操作后,请不要依靠操作系统进行清理。自己清理一下。
kill -9
爱好者……)
std::exit
会调用dtor,std::abort
不会,未捕获的异常可能会。
这更可能取决于操作系统而不是语言。最终,任何语言的任何程序都将从操作系统获取其内存。
我从未听说过在程序退出/崩溃时不会回收内存的操作系统。因此,如果您的程序在需要分配的内存上具有上限,那么仅分配而不永不释放是完全合理的。
所有带有标题的操作系统都将清除终止后您的过程造成的混乱。但是总是有无法预料的事件,如果以某种方式被拒绝访问并且某个可怜的程序员没有预见到这种可能性,那么它以后不会再尝试怎么办?如果内存泄漏是关键任务,则总是更安全地清理自己即可;否则,如果付出高昂的代价,IMO真的不值得付出这种努力。
编辑:如果确实存在内存泄漏,那么您确实需要清理内存泄漏,例如循环。我所说的内存泄漏是在整个程序过程中不断累积的,如果您有任何其他类型的泄漏,迟早很可能是一个严重的问题。
从技术上讲,如果泄漏是内存“复杂性” O(1),则在大多数情况下都可以,O(logn)已经令人不快(在某些情况下是致命的),并且O(N)+无法忍受。