代码之家  ›  专栏  ›  技术社区  ›  Nathan Wheeler

文本框。WPF应用程序中的文本泄漏内存

  •  3
  • Nathan Wheeler  · 技术社区  · 14 年前

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

    在运行应用程序几个小时后,它会因OutOfMemoryException而崩溃。我在上面运行了CLRProfiler,发现泄漏发生在显示数组当前状态的文本框中。。。应用程序在Char[]中构建~4K,每次接口更新时,挂起内存的每个位的堆栈跟踪都是相同的。

    这是WPF中的一个bug,还是我不知道应该做些什么来防止这种情况发生?我没有看到其他任何关于这个的参考资料。由于这是一个相当处理器密集型的操作,如果我不必仅仅显示数组的当前状态,我宁愿不必销毁和重建TextBox。

    这是我能找到的唯一的内存泄漏,但是由于所需操作的数量太多,它实际上是应用程序的一个大问题,即使我只是简单地减少接口更新的频率。如果您需要更多信息,我会尽可能提供帮助,但请理解,由于此应用程序的功能,我几乎不能发布任何源代码,我将不得不匿名发布任何我可以发布的内容(删除任何应用程序用途的指示)。

    <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更新的代码是:

            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;
    
    2 回复  |  直到 13 年前
        1
  •  17
  •   Hans Passant    12 年前

    从TextBoxBase.UndoLimit属性的文档中:

    表示撤消队列仅限于

    你找到了极限。将其设置为合理的小值。

    否则,在文本框中显示日志信息通常意义不大。它实际上是允许用户输入文本。也许TextBlock是一个更好的选择。


        2
  •  2
  •   user1228 user1228    14 年前

    +汉斯一个。

    arraystatus (据我所知可能是100k)每次更新UI时,StringBuilder都会变得毫无意义。

    s.Append(i.ToString());
    s.Append(":\t");
    s.Append(item.ToString());
    s.Append(i % 8 == 0 ? "\n" : "\t"));
    

    AppendFormat .