我在 WPF 中构建的 UI 框架中遇到垃圾收集问题。我在引号中使用内存泄漏,因为我认为我理解这个问题,但没有解决方案或某种解决方法。
当我创建 UIElements 但不显示它们时会出现此问题。从 UI 的角度来看,我使用的是虚拟化列表视图 (GridView)。所以所有的行都不会一次显示。在我的一个用例中,我创建了一个导出行功能,它能够将所有行导出到 csv。通常,行中的单元格由字符串或整数等基元组成。
棘手的地方是一些单元格本身就是 UIElements,这也是列表被虚拟化的原因之一(制作一些单元格的成本非常耗时,并且可能会占用内存)。所以我只在被问到时创建 UIElements,然后我什至不缓存它们(使它们有资格被收集)。
当我通过行提供程序枚举时访问属性时会出现此问题。创建并返回 UIElement,从中提取数据,写入 csv,然后查看下一行。在这个循环中,没有对这些行(ViewModel 类)的引用,因此人们会认为它们有资格进行垃圾收集。情况似乎并非如此。使用.Net Memory Profiler,我推断出我的“内存不足异常”是UIElements被PriorityQueue中的DispatcherOperation(来自Dispatcher)保留在内存中的结果。我认为这是因为它们正在等待显示(但从不显示)。
如果我没有得到内存不足的异常,最终这些 UIElements 似乎是通过 PriorityQueue 处理的(我猜它放弃了)并且被垃圾收集。这是最好的情况。当我处理少量行时,这似乎很好。但是当我们进入 50,000 - 100k 级别时,情况就不同了。我可以向您保证,没有其他对这些 ViewModel 或 UIElements 本身的引用(在 DispatcherOperation 之外)。
关于如何解决此问题或解决此问题的任何想法?有没有办法阻止这些未显示且很快将被使用的 UIElements 的排队?
编辑 01/25/2013:我意识到我可能需要专门清理内存中保存的内容。行对象,因为它们没有对 UIElement 的引用,它们没有保存在内存中(这很好)。只有通过 Get 访问器访问的 UIElement 会留在内存中。对它们的唯一引用是 PriorityQueue 而不是我自己的代码。