• WPF的TextBox产生内存泄露的情况


    前段时间参与了一个WPF编写的项目,在该项目中有这样一个场景:在程序运行过程中需要动态地产生大量文本信息,并追加WPF界面上的一个TextBox的Text中进行显示。编写完之后,运行该项目的程序,发现在产生大量信息之后,发现系统变慢了,打开任务管理器才发现,该项目的程序占用了将近1.5G的内存(天啊!!!这不是一般的耗内存啊!!!)。后来通过查资料和探索才发现了WPF的TextBox在追加Text显示文本时会造成内存泄露。下面通过一个小Demo程序来展示一下这个内存泄露。

    我的Demo程序很简单,就是在界面上显示一个TextBox和一个Button,点击Button后就从0到9999进行for循环并将这些数字追加的TextBox的Text中进行显示。代码如下,

    MainWindow.xaml
    <Window x:Class="TextBoxMemoryLeak.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="测试TextBox内存泄露" Height="350" Width="525"
            WindowStartupLocation="CenterScreen">
        <Grid Margin="5">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="35" />
            </Grid.RowDefinitions>
            <DockPanel Grid.Row="0">
                <TextBox Name="tbOutput" IsReadOnly="True" VerticalScrollBarVisibility="Auto"/>
            </DockPanel>
            <StackPanel Grid.Row="1"
                        FlowDirection="RightToLeft"
                        Orientation="Horizontal">
                <Button Name="btnStart" Content="开 始" Margin="5,4,5,4" Width="65" Click="btnStart_Click" />
            </StackPanel>
        </Grid>
    </Window>
    MainWindow.xaml.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace TextBoxMemoryLeak
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                this.btnStart.IsEnabled = false;
                this.tbOutput.Text = "";
    
                for (int i = 0; i < 10000; i++)
                {
                    //使用此语句进行Textbox的追加会造成内存泄露
                    //this.tbOutput.Text += string.Format("{0}\n", i);
    
                    //使用此语句进行Textbox的追加可避免内存泄露
                    this.tbOutput.AppendText(string.Format("{0}\n", i));
                }
    
                this.btnStart.IsEnabled = true;
            }
        }
    }

    界面如下所示:

     

    内存泄露情况

    最初我们采用的是TextBox的Text追加方式如下

    this.tbOutput.Text += string.Format("{0}\n", i);

    构建,启动调试后,我们查看任务管理器,此时所占内存只有16M,

     

    点击【开始】按钮之后,等到从0输出到9999之后,我们再查看任务管理器,发现此时所占的内存飙到了600+M,

     

    若此时再点击【开始】按钮,等循环结束,发现所占内存飙到了900+M,

     

    再点击【开始】按钮的话,就要发生OutOfMemory异常的。当我们将循环改为从0到19999时,第一次点击【开始】按钮,我的机器就发生OutOfMemory异常了。

    避免内存泄露的情况

    将TextBox的Text追加方式改为下面语句

    this.tbOutput.AppendText(string.Format("{0}\n", i));

    构建,启动调试,然后点击界面的【开始】按钮,等循环结束,我们查看任务管理器,测试Demo程序只占了29M内存(此时是从0到19999的循环)。

     

  • 相关阅读:
    堆排序
    深入理解创建类设计模式(Creational Patterns)
    (Head First)设计模式基础
    SpringMVC中的适配器模式应用
    软工团队任务
    visio画UML用例图
    安卓架构设计
    结对项目编程之代码进展
    工大助手(爬虫——查成绩部分)
    设计模式
  • 原文地址:https://www.cnblogs.com/lienhua34/p/2917600.html
Copyright © 2020-2023  润新知