使用FreeImage.Net转换图片时内存泄漏,调用dib.SetNull()无法释放
内存泄漏原因
- FreeImage核心逻辑由C语言实现,
FreeImage.Load方法分配的图片存储内存属于非托管堆资源,.NET垃圾回收器无法自动感知、回收这类资源,必须主动调用对应释放接口。 dib.SetNull()仅会清空托管层面的FIBITMAP对象指针引用,不会触发底层非托管内存的释放逻辑,因此你当前的代码相当于直接丢弃了非托管内存的地址引用,资源会一直占用到进程退出。
解决方法
首先必须在图片处理完成后调用FreeImage.Unload(dib)主动释放底层非托管内存,再调用SetNull()清空托管引用。推荐配合try-finally结构保证异常场景下资源也能正常释放,避免偶发泄漏,参考实现如下:
var dib = new FIBITMAP(); try { dib = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_PNG, pngFile.FullName, FREE_IMAGE_LOAD_FLAGS.DEFAULT); FreeImage.Save(FREE_IMAGE_FORMAT.FIF_JP2, dib, jpgFile.FullName, FREE_IMAGE_SAVE_FLAGS.JPEG_OPTIMIZE); } finally { // 优先释放非托管资源 if (!dib.IsNull) { FreeImage.Unload(dib); } // 清空托管指针引用 dib.SetNull(); }
如果是批量处理大量图片的场景,需保证每处理完单张图片就立刻执行释放逻辑,不要堆积等待GC触发,避免进程内存占用过高。
内容的提问来源于stack exchange,提问作者Tib Schott
相关产品推荐
相关产品推荐

