记ArcObject开发中一次内存泄露问题

在开发桌面GIS处理软件的过程中,遇到了一个程序闪退的问题,问题也很简单,在导出少量数据时没有发生程序闪退,但是在处理大量数据的过程中,出现了程序闪退的问题;这自然而然的让我想到了内存泄露的问题,但是由于C#桌面端开发做的不多,怎么定位内存泄露的变量成了我的问题。

1.找工具

首先采用debug的运行方式运行程序,直到程序闪退,抛出异常,果不其然是OutOfMemory问题。抛出异常的程序位于循环之内,也印证了内存泄露的问题。下一步就是看看有什么是使用过程中没有释放的对象,因为代码是别人写的,看了半天也没有发现具体是哪个变量(这一步比较考验编码经验,也可能是我经验欠缺,总之是没发现什么问题)。
然后就考虑上工具,上啥工具咱也没经验,百度一下呗,发现了两个方案:Visual Leak Detector和Visual Studio自带的诊断工具,前者看着很牛逼的样子,看了一下博客介绍,可以直接定位到内存泄露的行,这感觉可以呀,可一看人家的代码是C语言的,咱这是C#呀,不明觉厉呀,算了,还是看看VS自带的诊断工具吧。

2.学习工具

这里可以看这篇博客:vs内存泄漏三种检测方式
1.调试-》窗口-》显示诊断工具
在这里插入图片描述
2.在要调试的地方打断点,诊断窗口选择内存使用率
在这里插入图片描述
3.到第一个断点处,点击截取快照
在这里插入图片描述
在这里插入图片描述
4.执行下一句断点调试,再点击截取快照,如果内存使用增加就会出现变化
在这里插入图片描述

3.定位问题

在第二节中使用诊断工具3、4步多次测试,发现内存泄露的数据结构,这里由于单个数据比较小,可能看不出差异,又由于处于循环中,所以在代码中加上个每隔10000次循环中断一次的端点,这样便于发下内存泄露的点。
在这里插入图片描述
这里发现是ComReleaser对象出现的内存泄露。
于是查看源代码

comReleaser.ManageLifetime(featureBuffer);

featureBuffer该变量在循环中创建,每创建一个上面的语句就会将其添加到comreleaser中,而释放内存的代码在循环之外,导致循环过程中内存爆炸

4.解决

这里将上述代码注释掉,不去进行手动管理内存,而是将内存回收交还给C#的GC,测试之后发现内存泄露问题解决,Bingo!

猜你喜欢

转载自blog.csdn.net/zhoulizhu/article/details/129878397