Nat*_*ler 3 c# wpf textbox memory-leaks
我有一个应用程序在数组数组上进行大量的数字运算.我将其设置为每100,000次操作以显示这些数字的状态.这只是应用程序仍处理的操作员的可视指示,以及完成的距离.
运行应用程序几个小时后,它会崩溃并出现OutOfMemoryExeption.我在上面运行了CLRProfiler,发现在TextBox中发生泄漏,显示了数组的当前状态......每次接口更新时,应用程序在Char []中构建~4K,每个位的堆栈跟踪挂起记忆是一样的.
这是WPF中的一个错误,还是我不知道应该做些什么来防止这种情况发生?我没有看到任何其他参考.因为无论如何这是一个非常耗费处理器的操作,如果我不必只显示数组的当前状态,我宁愿不必销毁和重建TextBox.
这是我能找到的唯一内存泄漏,但是由于所需的操作数量庞大,这对应用程序来说实际上是一个大问题,即使我只是降低了接口更新的频率.如果您需要更多信息,我会尽可能提供帮助,但请理解由于此应用程序的作用,我几乎不能发布任何源代码,我将不得不匿名化任何内容(删除任何指示应用程序的目的)我可以发布.
当通过CLR Profiler(DRASTICALLY降低性能)运行时,每2秒发生以下相同的跟踪(记住:100,000次操作)并且永远不会释放内存.当它在没有附加分析器的情况下运行时,更新之间的时间<1秒.
一次更新("Who Allocated")的跟踪是:
<root> : 3.7 kB (100.00%)
WpfApplication0.App::Main static void (): 3.7 kB (100.00%)
System.Windows.Application::Run int32 (): 3.7 kB (100.00%)
System.Windows.Application::Run int32 (System.Windows.Window): 3.7 kB (100.00%)
System.Windows.Application::RunInternal int32 (System.Windows.Window): 3.7 kB (100.00%)
System.Windows.Application::RunDispatcher Object (Object): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::Run static void (): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::PushFrame static void (System.Windows.Threading.DispatcherFrame): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::PushFrameImpl void (System.Windows.Threading.DispatcherFrame): 3.7 kB (100.00%)
NATIVE FUNCTION ( UNKNOWN ARGUMENTS ): 3.7 kB (100.00%)
MS.Win32.HwndSubclass::SubclassWndProc int_ptr (int_ptr int32 int_ptr int_ptr): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::Invoke Object (System.Windows.Threading.DispatcherPriority Object): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::InvokeImpl Object (System.Windows.Threading.DispatcherPriority Object bool): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::WrappedInvoke Object ( Object bool ): 3.7 kB (100.00%)
System.Windows.Threading.ExceptionWrapper::TryCatchWhen Object (Object Object bool ): 3.7 kB (100.00%)
System.Windows.Threading.ExceptionWrapper::InternalRealCall Object ( Object bool): 3.7 kB (100.00%)
MS.Win32.HwndSubclass::DispatcherCallbackOperation Object (Object): 3.7 kB (100.00%)
MS.Win32.HwndWrapper::WndProc int_ptr (int_ptr int32 int_ptr int_ptr bool&): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::WndProcHook int_ptr (int_ptr int32 int_ptr int_ptr bool&): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::ProcessQueue void (): 3.7 kB (100.00%)
System.Windows.Threading.DispatcherOperation::Invoke Object (): 3.7 kB (100.00%)
System.Threading.ExecutionContext::Run static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 3.7 kB (100.00%)
System.Threading.ExecutionContext::RunInternal static void (System.Threading.ExecutionContext System.Threading.ContextCallback Object): 3.7 kB (100.00%)
System.Threading.ExecutionContext::runTryCode static void (Object): 3.7 kB (100.00%)
System.Windows.Threading.DispatcherOperation::InvokeInSecurityContext static void (Object): 3.7 kB (100.00%)
System.Windows.Threading.DispatcherOperation::InvokeImpl void (): 3.7 kB (100.00%)
System.Windows.Threading.Dispatcher::WrappedInvoke(1) Object ( Object bool ): 3.7 kB (100.00%)
System.Windows.Threading.ExceptionWrapper::TryCatchWhen(1) Object (Object Object bool ): 3.7 kB (100.00%)
System.Windows.Threading.ExceptionWrapper::InternalRealCall(1) Object ( Object bool): 3.7 kB (100.00%)
System.Delegate::DynamicInvokeImpl Object (Object[]): 3.7 kB (100.00%)
System.Reflection.RuntimeMethodInfo::Invoke Object (Object System.Reflection.BindingFlags System.Reflection.Binder Object[] System.Globalization.CultureInfo bool): 3.7 kB (100.00%)
System.RuntimeMethodHandle::InvokeMethodFast Object (Object Object[] System.Signature System.Reflection.MethodAttributes System.RuntimeTypeHandle): 3.7 kB (100.00%)
WpfApplication0.Window1::UpdateUI void (): 3.7 kB (100.00%)
System.Windows.Controls.TextBox::set_Text void (String): 3.7 kB (100.00%)
System.Windows.DependencyObject::SetValue void (System.Windows.DependencyProperty Object): 3.7 kB (100.00%)
System.Windows.DependencyObject::SetValueCommon void (System.Windows.DependencyProperty Object System.Windows.PropertyMetadata bool System.Windows.OperationType bool): 3.7 kB (100.00%)
System.Windows.DependencyObject::UpdateEffectiveValue System.Windows.UpdateResult (System.Windows.EntryIndex System.Windows.DependencyProperty System.Windows.PropertyMetadata System.Windows.EffectiveValueEntry System.Windows.EffectiveValueEntry& bool System.Windows.OperationType): 3.7 kB (100.00%)
System.Windows.DependencyObject::NotifyPropertyChange void (System.Windows.DependencyPropertyChangedEventArgs): 3.7 kB (100.00%)
System.Windows.Controls.TextBox::OnPropertyChanged void (): 3.7 kB (100.00%)
System.Windows.FrameworkElement::OnPropertyChanged void (): 3.7 kB (100.00%)
System.Windows.DependencyObject::OnPropertyChanged void (System.Windows.DependencyPropertyChangedEventArgs): 3.7 kB (100.00%)
System.Windows.Controls.TextBox::OnTextPropertyChanged static void ( ): 3.7 kB (100.00%)
System.Windows.Documents.TextContainer::DeleteContentInternal void (System.Windows.Documents.TextPointer System.Windows.Documents.TextPointer): 3.7 kB (100.00%)
System.Windows.Documents.TextTreeUndo::CreateDeleteContentUndoUnit static System.Windows.Documents.TextTreeDeleteContentUndoUnit (System.Windows.Documents.TextContainer System.Windows.Documents.TextPointer System.Windows.Documents.TextPointer): 3.7 kB (100.00%)
System.Windows.Documents.TextTreeDeleteContentUndoUnit::.ctor void (System.Windows.Documents.TextContainer System.Windows.Documents.TextPointer System.Windows.Documents.TextPointer): 3.7 kB (100.00%)
System.Windows.Documents.TextTreeDeleteContentUndoUnit::CopyContent ContentContainer (System.Windows.Documents.TextTreeNode System.Windows.Documents.TextTreeNode): 3.7 kB (100.00%)
System.Windows.Documents.TextTreeDeleteContentUndoUnit::CopyTextNode System.Windows.Documents.TextTreeNode (System.Windows.Documents.TextTreeTextNode System.Windows.Documents.TextTreeNode ContentContainer&): 3.7 kB (100.00%)
System.Char [] : 3.7 kB (100.00%)
Run Code Online (Sandbox Code Playgroud)
并且生成UI更新的代码是:
List<int> arraystatus = new List<int>(displayarray.ToArray());
StringBuilder s = new StringBuilder();
int i = 1;
foreach (int item in arraystatus)
{
s.Append(i.ToString() + ":\t" + item.ToString() + (i % 8 == 0 ? "\n" : "\t"));
i++;
}
txtStatus.Text = s.ToString();
arraystatus = null;
s = null;
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 17
从TextBoxBase.UndoLimit属性的文档:
撤消队列中存储的操作数.默认值为-1,表示撤消队列仅限于可用的内存.
你发现了这个限制.将其设置为相当小的值.
否则,在TextBox中显示日志记录信息通常没有多大意义.它的确意味着允许用户输入文本.也许TextBlock是更好的选择.
更新:在.NET 4.5中,默认值-1更改为100以避免这种失控的内存使用情况.
| 归档时间: |
|
| 查看次数: |
3129 次 |
| 最近记录: |