在嵌入式操作系统中不会释放WeakReferences

时间:2012-04-16 11:25:02

标签: c# memory-leaks weak-references

我在这里有一个奇怪的行为: 我在运行在DLOG终端(Windows Embedded Standard SP1)上运行的WPF应用程序的生产中出现大量内存泄漏,如果我在普通桌面(Win7教授)上运行它,它表现得非常好。

在多次尝试找不到任何问题之后,我将其中一个直接放在我的显示器旁边,安装了ANTs MemoryProfiler并在终端和我的开发PC上模拟用户操作进行了一小时的测试运行。

结果是,由于一些奇怪的原因,嵌入式系统堆积了大量的WeakReference和EffectiveValueEntry []对象。

以下是一些图片:

开发(PC): enter image description here

enter image description here

终端: enter image description here

看看课程列表...... enter image description here

之前有没有人见过这样的东西,有没有已知的解决方案? 我在哪里可以得到帮助?

(PS安装了为.net4准备的图像的终端)

PPS:对于亲密选民:我认为问题很明确:我该如何解决这个问题。 你可以争论这是一个IT / OS问题还是一个编程问题,但我认为如果我在服务器故障中发布这个问题,它将立即得到一个非主题关闭...

更新: 我能够找到问题的很大一部分 - 但感觉有点像C ++: 我为WPF-List使用类似ViewModel的Items类,它提供(以及其他)ICommand(RelayCommand-pattern)。在视图的ViewModel-Property的getter中动态创建的Items似乎应用程序/ GC从未释放那些未使用的命令 - 或者对其CanExecuteChanged的订阅 - 内存分析器显示那些“由a持有弱参考“。我更改了我的代码以重用那些item-viewmodel和Dispose / set以使其Dispose中的每个已使用的属性都为null,并将其用作清理 - 就像我说的那样:在旧的C ++时代感觉就像“删除”。 最重要的是我使用强制GC.Collect每30分钟(是的我知道 - 你永远不应该 - 但我到目前为止没有其他解决方案)。 使用此设置,应用程序运行6个小时到目前为止没有问题,但感觉不对。

我无法理解为什么那些WeakReferences没有被声称,因为它们在我的台式机上...

对此有何想法?请!

更新: 我仍然无法确定这个问题,但我看到一个奇怪的行为: 如果我使用PC-Anywhere在其中一个终端上观察我的软件操作,问题就会消失! 即使在运行8小时后。直接软件运行它应该 - 它甚至会释放内存(我在主屏幕上放了一个小记忆计数器 - 让我说我连接到终端并看到内存很低 - 等待几分钟后内存被回收)

所以我认为Devin(下面的一个答案)在正确的方向上有领先优势 - 远程控制软件中的某些内容解锁终结器线程或阻止GC的任何东西 - 无论是模拟键盘/鼠标还是其他任何东西。 / p>

对此有何想法?

2 个答案:

答案 0 :(得分:5)

我们在平板电脑上运行我的应用程序时出现了(有些)类似的问题。在桌面上运行时将回收内存,但在平板电脑或使用PC输入面板的其他设备上运行时则不会回收。问题是终结队列被卡住了。 COM对象终结器正在等待在主线程上运行某些东西,该主线程没有消息循环。

解决方案是找到足够的时间来调用Application.DoEvents()。我们有一个间歇性调用的方法,我们每隔10次调用就会调用它。我不知道这是否与你所遇到的问题相同,但也许它可以解释一下。

编辑:我确实需要说清楚,一般来说,调用DoEvents()是个坏主意。它适用于这种情况,因为该线程上没有任何UI或这些事件可能干扰的任何其他事件。

答案 1 :(得分:2)

从截图中可以看出,LOH在使用空间不会增长的同时增长。 LOH中的可用空间增长很多,这表明由于固定对象导致内存碎片化。这看起来像一个卡住的终结器线程,它确实阻止了托管对象的清理。您应该获得内存转储并检查终结器线程被卡住的方法。使用Windbg,您可以轻松完成此任务。