Failed to allocate memory for image

开发环境

VS2022

SimpleITKCSharplanaged.dll 4.11

现象

调用某给出的方法时出现下述错误:

引发的异常:“System.ApplicationException”(位于SimpleITKCSharpManaged.dll 中)“System.pplicationException”类型的常在 SimpleITKCSharplanaged.dll中发生,但未在用户代码中进行处理Exception thrown in SimplelTk Resamplenagerilter Execute: c:dvs10-04-pkglsinpleitk-buildlitk- prefixincludelitk-4. 1litknportInagecontainer.hxx:19 Failed to allocate memory for image.

详细如下截图:

分析

从看到的“Failed to allocate memory for image.” 这条信息来看,就是分配给image的内存失败了。于是怀疑程序对于某些需要释放的对象没有正常的释放(可能是托管对象,也可能是非托管对象),导致其在资源不能被回收,同时每次调用还在实例化,导致其内存占用就不断增长。

以下为出错时的内存快照,可以看出内存确实是在不断增长的,增长到接近71.2G的样子。在内存耗尽之后,肯定就会出现不能分配内存的问题。

 下图为程序报错时的情况,报错后程序的内存也明显得到了释放。但是再次运行时又会内存激增。

解决方案

查看某给出的调用方法中的Image,如下图所示,其都是由itk中提供的Image。

itk中的Image应该是有一个Dispose方法,尝试可知itk中的Image确实是有Dispose方法的,也就是说Image是需要显示释放资源的,否则就会造成它的资源不能被及时回收,从而导致其内存激增,最后导致整个程序运行报错。

在将image及时Dispose后,再次运行程序,这次内存没有再出现内存激增的情况。

C#常见需要Dispose对象

对于C#这种托管语言,大多数时候是不需要显示释放资源的,但一些非托管的资源必须手动进行释放。

常见的如:

文件流——文件读取时常用

内存流

图像——图像处理的时候常用,主要是Bitmap

进程——进程操作或多进程处理

更多的可详细见IDisposable的派生类。

如何预防

特别注意,对于调用他人开发的dll或程序时,一定要仔细查看资源是否需要显示Dispose,若需要释放,则一定要释放。

除了开发时注意外,还有就是提到的诊断工具要利用起来。在提交代码前,最好在监控内存的情况下运行下程序,最大限度的避免此类错误提交到了仓库中。监控时,主要观察内存是否激增,对象数量是否有明显增加。

最后就是不断总结、积累。毕竟成长的路上,谁又不会摔倒呢?

参考资源

IDisposable 接口 (System) | Microsoft Learn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值