首页 > 解决方案 > Marshal.AllocHGlobal 是否创建 Windows 内核句柄?

问题描述

我们有消耗大量内存的 Windows 服务。它使用通过调用 Marshal.AllocHGlobal 分配的自定义非托管结构。这些结构几年前由一个不知名的程序员实现。当然,今天我们有内存泄漏。在调查这个问题的过程中,我们注意到我们的非托管结构并不总是正确地被释放。我们已经修复了它,但还有一个问题:如果服务崩溃怎么办?

Marshal.AllocHGlobal 是否创建 Windows 内核句柄?

据我所知,系统的句柄数量有限,应该明确释放句柄。如果我们不释放它们,它们就会挂起,直到系统重新启动。SafeHandle 是为保证释放 Windows 系统句柄(如文件描述符)而创建的。SafeHandle 继承自“神奇”类 CriticalFinalizerObject,它改变了 GC 行为:它保证了终结。

我们应该从 CriticalFinalizerObject 继承我们的结构吗?

标签: c#.net

解决方案


Marshal.AllocHGlobal 是否创建 Windows 内核句柄?

是的,因为根据文档

此方法从 Kernel32.dll公开 Win32 LocalAlloc函数。

所以:

我们应该从 CriticalFinalizerObject 派生我们的结构吗?

不。

据我所知,系统的句柄数量有限,应该明确释放句柄。如果我们不释放它们,它们就会挂起,直到系统重新启动。

错误的。Windows 不会丢失句柄数。当请求句柄的进程退出时,它的句柄被释放。

SafeHandle 是为保证释放 Windows 系统句柄(如文件描述符)而创建的。SafeHandle 派生了“神奇”类 CriticalFinalizerObject,它改变了 GC 行为:它保证了终结。

错误的。如果您的服务崩溃,它的终结器如何运行?


推荐阅读