程序退出时,泄漏的内存是否被释放?

157
如果我在编程时无意中造成了内存泄漏,而应用程序终止了,那么泄漏的内存会被释放吗?

1
非常有用,相关答案:https://unix.stackexchange.com/questions/275184/when-interrupting-a-process-does-a-memory-leak-occur/275280#275280 - Gabriel Staples
6个回答

202

是的,“内存泄漏”简单来说就是进程不再引用的内存,因此无法释放。操作系统仍会跟踪分配给进程的所有内存,并在该进程终止时释放它。

在绝大多数情况下,操作系统会释放内存,例如普通的Windows、Linux、Solaris等操作系统。但需要注意,在一些特定环境中,如各种实时操作系统,当程序终止时内存可能不会被释放。


6
问题:操作系统是否跟踪所有分配?任何你分配的堆内存都来自进程的虚拟内存空间 - 当进程终止时,该空间会被整体返回给系统,对吗?我不明白为什么需要额外的簿记,因为进行分配的进程是唯一可以访问这些页面的进程(在用户空间中)。或许我被误导了? - Chris Tonkinson
6
@Justin:如果不知道操作系统,我认为这不是有效的。也许明确指定您正在谈论的操作系统会更好。 - Brian R. Bondy
7
有许多用于小型设备等的实时操作系统不能回收因泄漏而丢失的内存。你的问题取决于你所谈论的操作系统。 - Brian Neal
1
@vartec:Nucleus RTOS……或者至少它的某些版本,在任务分配内存泄漏时不会回收泄漏的内存。可能有包括适当内存管理的Nucleus版本,这不是问题(或者可能是附加组件)。无论如何,我使用过一个版本,其中泄漏的内存真正泄漏,直到系统重置。 - Dan Moulding
19
即使使用了专门保护内存的操作系统,你仍然需要定义“泄露”。应用程序很可能会在其自身的内存空间之外分配“系统”资源(在Windows世界中通常使用句柄来标识这些资源)。关闭应用程序并不总是能确保释放此类资源。 - David
显示剩余3条评论

47

操作系统通常会清理未被显式释放的内存和未被显式关闭的句柄,但这并不受 C++ 标准的保证。你可能会发现一些嵌入式设备没有释放内存泄漏。

话虽如此,我见过的所有 Windows 和 Linux 发行版都会释放内存泄漏。

你可以轻松地创建一个巨大的内存泄露循环来测试它。观察你的 RAM 使用情况的增长,然后关闭你的程序。你会发现 RAM 使用情况回归正常。


在使用 C++ 时,另一个需要考虑的因素是,如果你没有删除堆分配的内存,那么你的析构函数也不会被调用。如果你的析构函数没有被调用,有时你还会遇到其他副作用。


17

您是否在桌面操作系统(Windows,Linux等)上运行? 如果是这样,一般情况下当程序退出时,系统会释放与该程序相关联的任何内存。


13
通常是这样的。有一些系统支持像共享内存块这样的东西,它们在程序退出时不会自动释放。大多数系统仍然保留一个引用计数,并在打开它的所有程序都退出后将其删除,但也有一些不会这样做(例如,16位Windows有一些类型的项目即使没有任何引用它们也会保持分配 -- 虽然通常在堆积足够的数量之前因其他原因而崩溃...)。

6
据我所知,现代操作系统会在程序终止后释放这段内存。

5

取决于您泄漏的内存是什么。有些内存无法被操作系统回收。然而,在大多数操作系统上,当进程退出时,大多数内存将自动被回收。


6
有些内存无法被操作系统回收,比如什么? - anon
2
在一些实时操作系统中,我看到过特殊的以太网缓冲块,当进程退出时不会被清除。 - Brian Neal
1
共享内存通常不会被回收,因为您可能希望它持续存在以供短暂进程使用。 - Brian Neal
AmigaDOS是(曾经是?)一个操作系统的例子,其中泄漏的内存在程序退出时不会被回收。这是AmigaDOS不支持虚拟内存的结果,因此所有程序实际上都在单个共享内存空间中作为“线程”运行,并共享单个堆。操作系统无法跟踪哪个程序分配了哪个缓冲区,因此无法自动清理。 - Jeremy Friesner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接