操作系统;自动清理资源

7

从这个答案开始:当C++终止处理程序是正确的时候?

如果有一个'自动清理'和'不会自动清理'的资源列表,并且可以指定操作系统/资源以及最好附带文档链接(如果适用),那就太好了。在您的答案中,如果您可以指定操作系统/资源并提供文档链接(如果适用),那就更好了。

显而易见的:

内存:是的,会自动清理。 问题。是否有任何例外情况?


能否提供一个反例,让我们了解你期望的是什么样的东西? - skaffman
复杂资源,例如服务(例如数据库)。 - Martin York
服务通常不属于进程。 - anon
1
@Neil:你的观点是什么?未正确清理的数据库连接可能导致数据丢失。因此,它是一个应该被很好地清理的资源。 - Martin York
数据库连接不等于数据库服务。你先使用了“服务”这个词,而不是我。 - anon
我重新表达一下我的评论。一个复杂的资源,例如来自另一个服务的资源(如DB连接)。 - Martin York
4个回答

5

当应用程序崩溃或退出时,Windows无法清理一些模糊的资源,并且这些资源没有被明确释放,主要是因为操作系统不知道是否需要保留这些资源。

  1. 临时文件 - 正如其他人所提到的。
  2. 全局注册的 WNDCLASS(“当 DLL 卸载时,由 DLL 注册的窗口类不会被注销。DLL 必须在卸载时显式注销其类。”MSDN)如果您的全局窗口类也有类 DC,则该 DC 也将泄漏。
  3. 全局 ATOM(一种相对有限的资源)。
  4. 使用 RegisterWindowMessage 创建的窗口消息 ID。这些是设计成会泄露的,因为没有 UnregisterWindowMessage
  5. Semaphore 和 Event 在技术上并没有泄漏,但是当拥有它们的应用程序退出而没有发出信号时,其他进程可能会挂起。对于 Mutex 不适用此规则。如果拥有应用程序退出,等待该 Mutex 的其他进程将被释放。
  6. 如果您在退出之前不注销 热键,则在 Windows XP 及更早版本中可能会存在一些残留的怪异现象。其他应用程序可能无法注册相同的热键。
  7. 在 Windows XP 及更早版本中,当进程崩溃后,僵尸控制台窗口仍然存活。 (具体来说,是创建控制台窗口的 GUI 应用程序。)它会出现在任务栏上。您所能做的就是最小化、还原或移动窗口。
  8. 错误的驱动程序可能会受到不显式释放资源的应用程序的影响。非分页池泄漏相当普遍。
  9. 复制到剪贴板的数据。我想这并不算,因为此时数据已经由操作系统拥有,而不是将其放置的应用程序。
  10. 全局安装的钩子在安装进程在删除钩子之前崩溃时不会被卸载。

3
在Windows中,你能够获得的几乎所有句柄实际上都应该由操作系统来管理,这就是为什么你只能获取一个句柄。这包括但不限于以下内容(列表摘自MSDN文档中的CloseHandle() API):
Communications device 
Console input 
Console screen buffer 
Event 
File 
File mapping 
Job 
Mailslot 
Mutex 
Named pipe 
Process 
Semaphore 
Socket 
Thread 
Token 

所有这些资源应该在应用程序关闭时被操作系统恢复,但可能不会立即恢复,这取决于其他进程对它们的使用情况。
其他操作系统也是同样的工作方式。很难想象一个名副其实的操作系统(我排除嵌入式系统等),在这种情况下不是这样 - 资源管理是操作系统的首要任务。

我们可以认为,通过句柄控制的任何内容最终都将被操作系统释放。 - Martin York
这取决于你所说的“释放”。崩溃的进程无法持有互斥锁(等待互斥锁的另一个进程将使用WAIT_ABANDONED获取所有权)。但对于信号量来说情况就不同了。如果另一个进程正在等待它,那么它就会挂起。如果你杀死了挂起的应用程序,那么系统会回收信号量对象。 - Adrian McCarthy
我有一个应用程序,当它崩溃时,通常会留下一个僵尸控制台窗口(它是一个创建控制台窗口的Windows应用程序)。我不得不定期重新启动以清理它们。 - Adrian McCarthy

3
任何异常都是一个缺陷 - 应用程序可能会崩溃并包含泄漏。操作系统需要可靠,即使面对编写不良的应用程序也不会耗尽资源。这也适用于非操作系统资源。向进程分配资源的服务需要在进程退出时释放这些资源。如果它们没有这样做,那么就是需要修复的错误。
如果您正在寻找可以在进程退出后持久存在的程序工件,则在Windows上至少有以下内容:
  • 创建而未使用 REG_OPTION_VOLATILE 的注册表键
  • 创建而未使用 FILE_FLAG_DELETE_ON_CLOSE 的文件
  • 事件日志条目
  • 用于打印作业的纸张

1
是的,那是理想情况。但并非所有资源都由操作系统拥有。 - Martin York
哪些资源最终不归操作系统所有? - anon
@Neil - 这取决于您如何定义操作系统。如果一个COM服务器在由您通过CoCreateInstance创建的单独进程中运行,那么它是否是由操作系统管理的资源?(在这种情况下,如果您退出,则COM子系统将关闭服务器) - Michael
@Martin,我不想这么说,但我认为你需要了解一下操作系统架构。文件系统是一种组织操作系统资源的方式——资源仍然归操作系统所有。 - anon
@Neil Butterworth:在这方面没有异议。我的观点仍然站得住脚。 - Martin York
显示剩余6条评论

3

临时文件是一个很好的例子,它不会被清理 - 句柄已释放但文件没有被删除。


一个很好的观点。但是临时文件就像未完成的打印作业一样——操作系统根本没有足够的信息来决定它们是否应该在进程终止时立即删除。但是它们最终都会被清除/清理/刷新/删除。 - anon
1
@Neil:你的意思是什么?这是一种资源,操作系统不会自动清理它。如果有机会,应该由应用程序清理,但由于问题而泄漏。我相信这就是这次讨论的重点。 - Martin York
临时文件的使用场景是什么,它们不应该超过进程的生命周期?我唯一看到的(误)用途是作为一种次要内存 - 但你应该依赖于操作系统的虚拟内存管理来完成这项工作。 - Joseph Garvin
在我曾经工作的一个程序中,为了查看从程序数据生成的PDF文件,它们被保存到临时文件中。 - CiscoIPPhone
@Joseph:临时文件可以用于缓存可能不适合于虚拟地址空间的数据。 - Adrian McCarthy
显示剩余2条评论

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