在.NET Compact Framework中寻找内存泄漏(WinCE 5)

时间:2010-11-16 22:28:51

标签: .net debugging memory-leaks compact-framework

我正在使用Compact .NET Framework v3.5下的Windows CE设备上的基于事务的系统。我们发现,随着越来越多的事务被执行,可用的内存越来越少。显然是某种内存泄漏。

每次交易后,我们会收到两个记忆读数;一个来自OS(一个PInvoke调用),另一个来自垃圾收集器。我们发现操作系统读数增加了内存使用量,而GC的读数保持相对稳定(大约1MB方差+ - )。

该应用程序利用Microsoft同步服务在几个本地数据库(SQL Server Compact v3.5)上存储信息,并将它们与远程服务器同步。

如果这是Windows XP,我只需使用WinDbg连接到可执行文件,并分析堆以查看我是否正在创建永远不会获得GC的对象。但是,我甚至不知道托管堆是否是问题。

所以这个问题分为两部分:

1)在托管应用程序(DataAdapters,Streams等)中以这种方式泄漏内存的可能原因是什么?

2)哪些调试工具/技术可以帮助我找出确切的问题?

我知道继续下去并不是很多,但在这个阶段我没有比这更多的信息。

谢谢!

2 个答案:

答案 0 :(得分:3)

有两种方法可以攻击它。首先是查看托管对象及其生命周期。您可以使用Remote Performance Monitor(RPM)查看GC堆的快照并进行比较。

您可以使用CLR Profiler检查调用树并查看这些对象的来源。

这两个工具通常可以让您找到托管代码问题。

现在,重要的一点是,你说GC没有报告任何增长,这告诉我GC堆很好,而且这些工具在这种特定情况下不太可能找到。尽管如此,我还是将这些工具放在一边,因为它们可能会帮助你(或其他人阅读这篇文章)。

在你的情况下,听起来你有原生的泄漏。你没有说出哪种类型的内存泄漏 - 物理或虚拟 - 但几乎可以肯定某些事情正在使得本机分配没有被释放。 SQL Compact是基于您对架构所说的内容的猜测,因为引擎是在本机代码中实现的,并且托管层位于其顶部。

我还要猜测,根本原因是你有一些小的托管对象(可能是一个SqlCeTransaction或SqlCeCommand),它们分别拥有一个小的托管占用空间,但是正在为你做一些原生分配,那些对象是幸存的。

托管工具应该允许您查找数量较多或数量较多的项目,并找到阻止GC杀死它们的根目录。验证您是否正在调用您正在使用的所有SqlCe对象上的Dispose也是一件好事。

如果所有这些都找不到,你可以深入研究一些native tools,但它们根本不能很好地使用托管代码,并且不太可能给你太多信息。

答案 1 :(得分:0)

听起来你好像错过了某个地方的EndInvoke?或者不关闭你的连接?

可能不是问题,但我们刚刚在我的工作中遇到了类似的问题......一对失踪的EndInvoke呼叫在几天的正常运行时间之后完全锁定了我们的服务器....就像我们在哪里一样不得不走下去,把箱子硬起来。