在 atexit() 函数中释放内存有什么意义吗?
我有一个全局变量,在启动后会被 malloc'ed。我可以编写一个 atexit() 函数来释放它,但是当程序退出时系统不会回收所有内存吗?
自己整理并积极清理有什么好处吗?
不是在 C 中 - 这就像在船沉没在你周围时重新布置躺椅一样。
在 C++ 中,答案是不同的,因为对象可以在其析构函数中删除临时文件等,因此您需要确保它们被调用。
释放它的一个好处是,如果您曾经做过任何内存泄漏测试,试图在进程的生命周期内将分配与解除分配相匹配,您将不会从这种故意泄漏中得到误报。
看到malloc()
/free()
通常涉及存在于用户空间中的大量数据结构,free()
当您的程序结束时占用内存实际上可能会消耗性能。如果部分数据结构被分页到磁盘,它们只需要从磁盘加载就被丢弃了!
然而,如果您在没有free()
ing 的情况下终止,则分页到磁盘的数据可以安然死去。
当然free()
,在其他时间 ing 通常是有益的,因为进一步malloc()
的 s 可以重新使用您释放的空间,free()
甚至可能取消映射一些内存,然后其他进程可以使用这些内存。
在所有现代操作系统中,您可以放心地假设程序退出时将释放所有内存。
实际上,当您的程序发展时,整洁会很有趣。它会在您创建“初始化”函数时强制您编写清理函数。当您的程序变得更加复杂并且您想要重新启动程序的一部分时,好处就来了。如果您已经编写了有效的清理函数,那么在“重新启动”程序的一部分时,您就不太可能突然忘记一些清理工作。
“懒惰”地编写清理函数,即仅在需要时更容易出错。编写清理函数迫使您考虑清理和最终的清理依赖。它允许在另一个项目中更轻松地重用您的部分代码。
所以是的,在 atexit 中释放是没有用的,关闭文件描述符也是如此。然而,随着代码的增长编写和维护清理功能可能是一个约束,会迫使你思考你在做什么
如果调用 atexit() 的代码是动态加载的共享库的一部分(例如,使用 dlopen()),则应该使用 free()。在这种情况下,将在 dlclose() 时间调用 atexit 处理程序,因此堆将继续存在以供进程的其余部分使用。
在 Windows 上,某些调用返回属于操作系统或 COM 的内存,您需要显式释放该内存,否则即使在您的进程终止后它也不会被释放。但这是一种罕见的情况。
在进程终止之前不释放内存不是内存泄漏。当你失去它的句柄时,这是一个内存泄漏。但是内存不是唯一的资源类型,其他资源会跨进程持续存在(如窗口句柄和文件句柄),因此您确实需要“释放”这些资源。