我在WPF中构建的UI框架中遇到了垃圾回收问题。我使用引号中的内存泄漏,因为我认为我理解了问题,但没有解决方案或某种解决方法。
此问题发生在创建UI元素但不显示它们时。从UI角度来看,我使用的是虚拟列表视图(GridView)。因此,并非所有行都会同时显示。在我的一个用例中,我创建了一个导出行特性,可以将所有行导出到csv。通常,行中的单元格由诸如字符串或整数之类的原始数据组成。
麻烦的是,某些单元格本身就是UI元素,这也是列表虚拟化的原因之一(制作某些UI元素的成本很高,可能会消耗大量内存)。因此,我只会在需要时创建UI元素,然后甚至不会对它们进行缓存(使它们有资格进行回收)。
当我在枚举行提供程序时访问属性时,问题就出现了。 UI元素被创建并返回,从中提取数据,写入到csv中,然后查看下一行。在此循环中,没有对这些行(ViewModel类)的引用,因此人们会认为它们应该有资格进行垃圾回收。但是事实似乎并非如此。使用.NET内存分析器,我推断出我的“内存不足异常”是由于DispatcherOperation(来自Dispatcher中的PriorityQueue)中保存了UI元素的原因。我假设这是因为它们正在等待显示(但从未实现)。
如果我没有得到内存不足异常,最终这些UI元素似乎会被处理掉(我猜测它放弃了),并且被垃圾收集。这是最好的情况。当我处理少量行时,这似乎没什么问题。但是当我们涉及50000-100k级别时,情况就另当别论了。我可以向您保证,这些ViewModel或UI元素本身(除了DispatcherOperation之外)都没有其他引用。
有什么想法可以解决或绕过这个问题吗?是否有办法阻止这些未显示且即将不再使用的UI元素排队?
编辑01/25/2013: 我意识到我可能需要澄清具体保存在内存中的内容。行对象没有对UI元素的引用,因此它们不保存在内存中(这很好)。唯一留下的是通过Get访问器访问的UI元素。它们唯一的引用是PriorityQueue,并没有我的代码。
此问题发生在创建UI元素但不显示它们时。从UI角度来看,我使用的是虚拟列表视图(GridView)。因此,并非所有行都会同时显示。在我的一个用例中,我创建了一个导出行特性,可以将所有行导出到csv。通常,行中的单元格由诸如字符串或整数之类的原始数据组成。
麻烦的是,某些单元格本身就是UI元素,这也是列表虚拟化的原因之一(制作某些UI元素的成本很高,可能会消耗大量内存)。因此,我只会在需要时创建UI元素,然后甚至不会对它们进行缓存(使它们有资格进行回收)。
当我在枚举行提供程序时访问属性时,问题就出现了。 UI元素被创建并返回,从中提取数据,写入到csv中,然后查看下一行。在此循环中,没有对这些行(ViewModel类)的引用,因此人们会认为它们应该有资格进行垃圾回收。但是事实似乎并非如此。使用.NET内存分析器,我推断出我的“内存不足异常”是由于DispatcherOperation(来自Dispatcher中的PriorityQueue)中保存了UI元素的原因。我假设这是因为它们正在等待显示(但从未实现)。
如果我没有得到内存不足异常,最终这些UI元素似乎会被处理掉(我猜测它放弃了),并且被垃圾收集。这是最好的情况。当我处理少量行时,这似乎没什么问题。但是当我们涉及50000-100k级别时,情况就另当别论了。我可以向您保证,这些ViewModel或UI元素本身(除了DispatcherOperation之外)都没有其他引用。
有什么想法可以解决或绕过这个问题吗?是否有办法阻止这些未显示且即将不再使用的UI元素排队?
编辑01/25/2013: 我意识到我可能需要澄清具体保存在内存中的内容。行对象没有对UI元素的引用,因此它们不保存在内存中(这很好)。唯一留下的是通过Get访问器访问的UI元素。它们唯一的引用是PriorityQueue,并没有我的代码。