我有一个类(参见下面的示例),它充当 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(); }