2009-10-26 67 views
4

在我的应用程序中,我有很多在运行时动态创建的RichTextBoxes。我意识到应用程序有一个内存泄漏,这是由RichTextBox控件引起的。为了证明,由于控制的内存泄漏我写了下面的测试方法:WPF RichTextBox内存泄漏

for (int i = 0; i < 3000; i++) 
     { 
      Control rich = new RichTextBox(); 
      pnl.Content = rich; 
     } 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

PNL是在XAML代码中声明一个ContentControl中。
如果您运行以下代码,则可以看到内存使用情况正在快速增长。

任何想法如何解决这个问题? 我曾考虑创建一个对象池,但这会使我的应用程序变得复杂,而我宁愿避免它。


编辑:我已经添加了调用垃圾收集器,以证明对象不被垃圾收集 - 没有在内存使用情况仍未改善,并没有调用GC收集方法。 请注意,在循环内调用rich.Dispose可消除内存使用增长。

+0

那你如何衡量内存? – 2009-10-26 16:01:43

+0

您可以在Windows任务管理器中看到内存使用增长 – Elad 2009-10-26 16:07:08

+0

这不限于RichTextBox。如果我在一个循环中运行代码,使用RichTextBox我会在大约一分钟内收到一个OutOfMemoryException异常 - 我的进程以32位进程的形式使用了所有2GB的可用空间。切换到一个普通的旧文本框,花了20分钟才能得到相同的异常。 – 2009-10-26 17:03:44

回答

2

在其他地方找到了这一点,就我的测试而言,它似乎是正确的。

当创建的FlowDocument, 相对昂贵的格式化 上下文对象还可用于 在其StructuralCache创建。当您在 循环中创建多个FlowDoc时,将为每个FlowDoc创建一个结构缓存 。让我们在循环结尾呼叫 Gc.Collect, 希望能够恢复一些内存。 StructuralCache有一个终结器 释放此格式上下文,但不是立即 。终结器 有效地将操作调度为 版本上下文,位于 DispatcherPriority.Background。

所以,如果在RichTextBox(或FlowDocument的)不漏油只是在后台线程等待清理。当它运行完全知道谁。我希望这只是实施了一种处理方法,可以立即强制清理。

+1

原文:http://social.msdn.microsoft.com/forums/en-US/wpf/thread/9cba6b80-c402-4f89-b300-6a9f8e4d7e37/ – Elad 2009-12-09 13:05:31

8

这并不表示您的应用程序有内存泄漏,这表示您的应用程序使用大量内存的。如果RichTextBox控件在超出范围之后的某个时刻没有被释放(检测到管理对象上的内存泄漏非常困难且无法证实),那么这就是泄漏。

一个常见的误解,即一个超出范围的对象将导致它被垃圾收集。这只是使其有资格收集。理论上,对象可以收集到从不收集直到应用程序终止。它与RichTextBox一起增长而不与其他控件一起增长的事实并不表示RichTextBox中存在内存泄漏,这只是表明它比其他控件每个实例使用的内存更多。尽管这些信息可能有用,但它在确定是否存在内存泄漏时无济于事。

+0

我的想法确切。 – 2009-10-26 15:21:28

+0

您是否尝试过运行测试代码?内存使用量迅速增长到整个计算机变慢的程度。您可以使用任何WPF控件来尝试代码,并且您会看到没有发生显着的内存增长。请注意,由新控件取代时,控件不在范围内 – Elad 2009-10-26 15:33:50

+0

@Elad:我已添加到我的答案中,以便更清楚一点。 – 2009-10-26 15:44:48

0

我们在winforms 2.0中遇到同样的问题,我们不得不购买第三方富文本控件。我想,微软并没有刻意去解决它......

+1

我很确定WinForms和RichTextBox的WPF版本之间没有实现类似的地方 – ArielBH 2009-10-26 16:41:15

0

关于您的编辑:

您已经将GC调用后循环终止与所有已创建3000个RichTextBox ES。

虽然我同意前面的一个在循环中没有被一个新循环取代时看起来很奇怪,但它是一个如此紧密的循环,以至于GC可能没有机会“做它的东西“在循环结束之前。

我不认为这是一个好主意(但它应该可以在测试代码中),但是您是否尝试过在循环内移动GC调用?

+0

我试过了你的建议,但它似乎没有任何效果。 – Elad 2009-10-26 16:54:11

+0

@Elad - 哦,好吧。这似乎是一个合理的建议。 – ChrisF 2009-10-26 17:31:19