元帅是否应将冻结的袋装放置在最终的阻塞中以确保资源被处置?
-
29-09-2019 - |
题
我有以下代码块:
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
SomeCommandThatCanThrowAnException();
Marshal.FreeHGlobal(unmanagedPointer);
如果将块包裹在尝试中,并将freeHglobal命令放在最后一个块中。 (如果中间命令抛出异常)。
似乎最终可以防止在这种情况下的内存泄漏,但是从我在网上找到的示例中,最终没有使用。也许无论如何资源都会自动处置(即使它们不受管理)。
解决方案
分配了元帅的不受管理的内存。所有chloblobal不会自动释放。
因此,将元帅.freehglobal放在 finally
块确实是一个好主意:
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
try
{
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
SomeCommandThatCanThrowAnException();
}
finally
{
Marshal.FreeHGlobal(unmanagedPointer);
}
您发现的示例可能会省略对简洁的错误处理。
如果您是出于长期目的分配不管理的内存(即不以相同的方法释放它),则可能有兴趣将指针包装在从源自的对象中 安全 (如 Safebuffer).
安全 实现IDIsposable模式,因此,当您处置对象或垃圾收集器收集对象时,未管理的内存将被释放。 Safehandle还源自CriticalFinalizerObject类,这意味着它将从CLR获得特殊治疗,以确保记忆力被释放。
class HGlobal : SafeBuffer
{
public HGlobal(int cb)
: base(true)
{
this.SetHandle(Marshal.AllocHGlobal(cb));
this.Initialize((ulong)cb);
}
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(this.handle);
return true;
}
}
例子:
using (var h = new HGlobal(buffer.Length))
{
h.WriteArray(0, buffer, 0, buffer.Length);
}
注意:Safebuffer是一只野兽,因此建议您谨慎。
注2:Safe Handers可以很好地与P/Invoke合作,并消除了完全通过INTPTR的需求。
SafeBuffers是为了安全地操纵C#的不受管理的内存,因此取决于您正在做的事情(分配了与P/Invoke一起使用的非管理内存,或者从C#中操纵未管理的内存),您应该选择Safehandle或SafeBuffer作为基础类。
其他提示
绝对地。它 绝不 自动释放,它是不受管理的内存。
不隶属于 StackOverflow