【发布时间】:2012-04-16 11:25:02
【问题描述】:
我在这里有一个奇怪的行为: 我在生产中运行 WPF 应用程序时遇到大量内存泄漏,该应用程序在 DLOG 终端(Windows Embedded Standard SP1)上运行,如果我在普通桌面(Win7 教授)上本地运行它,它的行为非常好。
在多次尝试发现任何问题均未成功后,我将其中一个直接放在显示器旁边,安装了 ANTs MemoryProfiler,并在终端和我的开发 PC 上模拟用户操作进行了一小时的测试运行。
结果是,由于一些奇怪的原因,嵌入式系统堆积了大量的 WeakReference 和 EffectiveValueEntry[] 对象。
这里有一些图片:
开发(PC):
还有终端:
只要看看班级列表...
以前有没有人见过这样的事情,是否有已知的解决方案? 我在哪里可以获得帮助?
(PS 安装了为 .net4 准备的图像的终端)
PPS:对于最接近的选民:我认为问题很明确:我该如何解决这个问题。 您可能会争论这是 IT/OS 问题还是编程问题,但我认为如果我将其发布在 Server Fault 中,它很快就会离题...
更新: 我能够找到问题的很大一部分——但感觉有点像 C++: 我为 WPF-List 使用类似 ViewModel 的 Items 类,它提供(以及其他)ICommand(RelayCommand-pattern)。在视图的 ViewModel-Property 的 getter 中动态创建的项目,似乎应用程序/GC 从未释放那些未使用的命令 - 或对其 CanExecuteChanged 的订阅 - 内存分析器将这些显示为“由弱参考”。我更改了我的代码以重用那些项目视图模型并将 Dispose/set 设置为 null 他们的 Dispose 中的每个使用的属性,并将其用作清理 - 正如我所说:在那些旧的 C++ 时代感觉就像“删除”。 最重要的是,我每 30 分钟使用一次强制 GC.Collect(是的,我知道 - 你永远不应该 - 但直到现在我没有其他解决方案)。 使用此设置,应用程序可以运行 6 多个小时,到目前为止没有任何问题,但感觉不对。
我不明白为什么这些 WeakReferences 没有像我的桌面计算机上那样被声明...
对此有什么想法吗?请!
更新: 我仍然无法确定这个问题,但我看到了一个奇怪的行为: 如果我使用 PC-Anywhere 观察我的软件在其中一个终端上的操作,问题就会消失! 即使在运行 8 小时后。软件直接运行 - 它甚至会释放内存(我在主屏幕上放了一个小内存计数器显示 - 假设我连接到终端并看到内存不足 - 等待几分钟后内存被回收)
所以我认为 Devin(下面的一个答案)在正确的方向上领先 - 远程控制软件中的某些东西解除了终结器线程或任何阻塞 GC 的东西 - 无论是模拟键盘/鼠标还是其他东西。
对此有什么想法吗?
【问题讨论】:
-
这是一个在没有附加调试器的情况下运行 VB.NET 程序集的调试版本的已知问题。它泄漏了自动生成的弱引用,以跟踪 WithEvents 事件以支持 Edit+Continue。除此之外,不可能从屏幕截图中逆向工程代码。
-
首先:这既不是 VB.NET 代码(无关紧要),也不是使用 DEBUG 集编译的 - 最重要的是,两者都在没有附加调试器的情况下运行,从同一版本开始使用相同的分析器,同时使用相同的程序集和文件(Xcopied)以及几乎相同的数据 - 你认为你可以从看到大量的 WPF 代码行中得到什么(或者你想要 all 代码 - 这是一些 MB 的文本文件......不是开源 BTW)
-
@HansPassant 提到的问题的参考(是的,VB.NET 在这里很重要):support.microsoft.com/?kbid=919481
-
是的,谢谢 - 但正如我所说,这个正在运行的应用程序附近没有调试器,也没有使用 DEBUG 编译,而且 kb 只提到了 vs2005 和 vs2010,所以 也许 它得到了从那以后的3年内固定...
-
我不明白为什么当您强制 GC.Collect(每 30 分钟)不强制它时会有所不同。如果您使用 ANTS 拍摄快照,它还会强制垃圾收集器运行,并且仍然存在具有“弱引用”的对象。你看过“实例保留图”吗?
标签: c# memory-leaks weak-references