我有一个类(参见下面的示例),它充当 CUDA 内存结构的 .NET 包装器,
使用 cudaMalloc() 分配并使用 IntPtr 类型的成员字段引用。
(该类使用包含各种 CUDA 功能的本机 C DLL 的 DllImport。)
dispose 方法检查指针是否为 IntPtr.Zero,如果不是,则调用 cudaFree()
成功释放内存(返回 CUDA 成功)
并将指针设置为IntPtr. 零。
finalize 方法调用 dispose 方法。
问题是,如果调用 finalize 方法而之前没有调用 dispose,
则 cudaFree() 函数会设置“无效设备指针”的错误代码。
我检查了一下,cudaFree() 接收到的地址与 cudaMalloc() 返回的地址相同,并且之前没有调用 dispose()。
当我添加对 dispose() 的显式调用时,相同的地址被成功释放。
我发现的唯一解决方法是不要从终结器调用 dispose 方法,但是,如果并不总是调用 dispose(),这可能会导致内存泄漏。
任何想法为什么会发生这种情况?- 我在 .NET 3.5 SP1 上的 Windows Vista 64 位 + GeForce 8800 和 Windows XP 32 位 + Quadro FX 上遇到了与 CUDA 2.2 和 2.3 相同的问题(不确定哪个数字)。
类 CudaEntity : IDisposable
{
私有 IntPtr 数据指针;
公共 CudaEntity()
{
// 通过 DllImport 调用 cudaMalloc(),
// 接收错误码,如果不为 0 则抛出期望
// 给 this.dataPointer 赋值
}
公共处置()
{
if (this.dataPointer != IntPtr.Zero)
{
// 通过 DllImport 调用 cudaFree(),
// 接收错误码,如果不为 0 则抛出期望
this.dataPointer = IntPtr.Zero;
}
}
~CudaEntity()
{
处置();
}
}
{
//这段代码有效
var myEntity = new CudaEntity();
myEntity.Dispose();
}
{
// 此代码导致“无效的设备指针”
// 终结器调用 cudaFree() 时出错
var myEntity = new CudaEntity();
}