WPF应用程序中的TextBox.Text泄漏内存 [英] TextBox.Text Leaking Memory in WPF Application

查看:84
本文介绍了WPF应用程序中的TextBox.Text泄漏内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对数字数组进行大量数字运算的应用程序.我将其设置为每100,000次操作以显示这些数字的状态.对于操作员来说,这只是视觉上的指示,表明该应用程序仍在处理中,以及完成该应用程序有多接近.

I have an application that does a large amount of number crunching on an array of numbers. I have it set to every 100,000 operations to display the status of those numbers. This is just sort of a visual indicator to the operator that the application is still processing, and how close it is to completed.

在运行该应用程序几个小时后,它因OutOfMemoryExeption崩溃.我在其上运行CLRProfiler,发现在TextBox中发生泄漏,该泄漏显示了数组的当前状态...每当接口更新时,应用程序都会在Char []中构建〜4K,每次挂起的位都将跟踪堆栈记忆是一样的.

After running the application for several hours, it crashes with an OutOfMemoryExeption. I ran CLRProfiler on it, and found that the leak is occurring in the TextBox that shows the current state of the array... the application builds ~4K in Char[] every time the interface updates, the stack trace for each bit of hung memory is the same.

这是WPF中的错误,还是我不知道应该做些什么来防止这种情况发生?我还没有看到对此的任何其他引用.由于无论如何这都是相当耗费处理器的操作,因此,如果我不必仅仅显示数组的当前状态,我宁愿不必销毁并重建TextBox.

Is this a bug in WPF, or is there something that I don't know I should be doing to prevent this from happening? I've not seen any other references to this. Since this is a pretty processor intensive operation anyway, I'd prefer not to have to destroy and rebuild the TextBox if I don't have to just to display the current state of the array.

这是我可以找到的唯一内存泄漏,但是由于所需的操作数量巨大,即使我只是降低了接口更新的频率,这实际上对于应用程序来说也是一个大问题.如果您需要更多信息,请在可能的情况下为您提供帮助,但请理解,由于此应用程序的作用,我几乎无法发布任何源代码,并且我必须匿名化任何内容(删除对应用程序的目的)我可以发布.

This is the only memory leak that I can find, but due to the sheer number of operations required, it's actually a big problem for the application, even if I simply reduce the frequency of the interface update. If you need more information, I'll assist if at all possible, but please understand that due to what this application does, I can't post hardly any source code, and I'll have to anonymize anything (removing any indication of the application's purpose) that I CAN post.

通过CLR事件探查器运行时(这会极大地降低性能),每2秒会发生以下相同的跟踪(请记住:100,000次操作),并且永远不会释放内存.在未连接分析器的情况下运行时,两次更新之间的时间为< 1秒.

When run through the CLR Profiler, which DRASTICALLY reduces performance, the following identical trace occurs every 2 seconds (remember: 100,000 operations) and the memory is never deallocated. When it's running without a profiler attached, the time between updates is < 1 second.

来自一次更新(分配给谁")的跟踪为:

The trace from one update ("Who Allocated") is:

<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%)

,生成UI更新的代码为:

and the code generating a UI update is:

        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;

推荐答案

来自TextBoxBase.UndoLimit属性的文档:

From the documentation of the TextBoxBase.UndoLimit property:

存储在撤消队列中的操作数.默认值为–1,即 表示撤消队列仅限于 可用的内存.

The number of actions stored in the undo queue. The default is –1, which means the undo queue is limited to the memory that is available.

您发现了该限制.将其设置为一个较小的值.

You found that limit. Set it to a reasonably small value.

否则,通常不会在TextBox中显示日志记录信息.这实际上是为了允许用户输入文本.也许TextBlock是更好的选择.

It otherwise doesn't normally make a lot of sense to display logging information in a TextBox. It is really meant to allow the user to enter text. Perhaps TextBlock is a better choice.

更新:在.NET 4.5中,默认值-1更改为100,以避免这种失控的内存使用.

UPDATE: in .NET 4.5, the default of -1 was changed to 100 to avoid this kind of runaway memory usage.

这篇关于WPF应用程序中的TextBox.Text泄漏内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆