C#、WPF、异步GUI更新和内存泄漏

C#、WPF、异步GUI更新和内存泄漏,c#,wpf,C#,Wpf,这东西漏水。随着任务的进行,我正在用一些进度信息更新GUI,它工作正常,但最后一行中的content.ToString()泄漏了。我只能推测,通过Dispatcher,将保留对该字符串的引用,直到它被销毁(当我关闭保存该字符串的对话框时,内存将被释放)。 很明显,正是字符串通过观察内存使用模式(开始缓慢,然后随着字符串变大而逐渐增加到10毫克)来吞噬内存,我还转储了挂起的进程(内存不足),并用windbg进行了调试。。一些跟踪将其放入许多char[]和gui框架文本框等。) 当我使用显式SetV

这东西漏水。随着任务的进行,我正在用一些进度信息更新GUI,它工作正常,但最后一行中的content.ToString()泄漏了。我只能推测,通过Dispatcher,将保留对该字符串的引用,直到它被销毁(当我关闭保存该字符串的对话框时,内存将被释放)。
很明显,正是字符串通过观察内存使用模式(开始缓慢,然后随着字符串变大而逐渐增加到10毫克)来吞噬内存,我还转储了挂起的进程(内存不足),并用windbg进行了调试。。一些跟踪将其放入许多char[]和gui框架文本框等。) 当我使用显式SetValue时,即使是异步的,为什么旧内容不能进行垃圾收集


忠告?:-)

首先,如果释放了引用,就不必担心内存问题,剩下的就交给垃圾收集器来完成它的工作

其次,您可以做的是通过限制对象在更高的世代中到达,使GC的工作更容易。如果可以在第一次扫描中清理对象,则GC首选

更多关于

垃圾收集器无法收集的问题是对象的生成

gen 0在取消引用后的第一次扫描中被清除

但如果垃圾回收清理内存时仍引用,则会将其升级到gen1

第二代等等

因此,为了最小化升级,您可以将该值复制到局部变量

范例

private delegate void UpdateTextBoxDelegate(System.Windows.DependencyProperty dp, Object     value);
..
UpdateTextBoxDelegate updateTextDelegate = new UpdateTextBoxDelegate(textBox1.SetValue);
..
foreach(..)
    Dispatcher.Invoke(updateTextDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { TextBox.TextProperty, content.ToString() });

忘记了这一点,答案是使用StringBuilder而不是普通字符串进行构建。

“很明显,是字符串占用了内存”:您是否尝试使用内存探查器查找泄漏源?这可能不是你所想的…我考虑过了,但为了我的生命,我不明白为什么它会更好…如果我在调用中执行content.ToString,它应该存在于比以前声明和分配它更窄的范围内。对吗?我将阅读您提供的“gc基础知识”,谢谢您。
foreach(..)
{
    string value = content.ToString();
    Dispatcher.Invoke(updateTextDelegate, DispatcherPriority.Background, new object[] { TextBox.TextProperty,  value });
}