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

  

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

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

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

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的循环)。

  

  本文来自lienhua34博客,原文地址:http://www.cnblogs.com/lienhua34/archive/2013/02/19/2917600.html

WPF的TextBox产生内存泄露的情况的更多相关文章

  1. 如何用Java编写一段代码引发内存泄露

    本文来自StackOverflow问答网站的一个热门讨论:如何用Java编写一段会发生内存泄露的代码. Q:刚才我参加了面试,面试官问我如何写出会发生内存泄露的Java代码.这个问题我一点思路都没有, ...

  2. 怎样用Java编写一段代码引发内存泄露

    通过下面步骤能够非常easy产生内存泄露(程序代码不能訪问到某些对象,可是它们仍然保存在内存中): 应用程序创建一个长时间执行的线程(或者使用线程池,会更快地发生内存泄露). 线程通过某个类载入器(能 ...

  3. 可能会导致.NET内存泄露的8种行为

    原文连接:https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/作者 Michael Shpilt.授权翻译,转载请保 ...

  4. linux下内存泄露检测工具Valgrind介绍

    目前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况. 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题. 推荐大家可以使用 ...

  5. ARC下内存泄露问题

    ARC下内存泄露问题 ARC下内存泄露问题,有需要的朋友可以参考下. iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下 ...

  6. Instruments指南:如何调试内存泄露

    Instruments指南:如何调试内存泄露 开篇 现在,你应该使用的ARC,而不是原来我们使用的MRC或者其他.但是我们在使用ARC的时候也会出现内存泄露的情况. 幸运的是,苹果为我们提供了Inst ...

  7. .Net 内存泄露

    一.事件引起的内存泄露 1.不手动注销事件也不发生内存泄露的情况 我们经常会写EventHandler += AFunction; 如果没有手动注销这个Event handler类似:EventHan ...

  8. 【转载】Java中如何写一段内存泄露的程序 & ThreadLocal 介绍和使用

    可以参考这段文章: link A1:通过以下步骤可以很容易产生内存泄露(程序代码不能访问到某些对象,但是它们仍然保存在内存中): 上文中提到了使用ThreadLocal造成了内存泄露,但是写的不清不楚 ...

  9. 深度:ARC会导致的内存泄露

    iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下面列举两种内存泄露的情况. 1,循环参照 A有个属性参照B,B有个属性 ...

随机推荐

  1. Linux上网设置

    ifconfig 命令查看网络设置 步骤1.配置/etc/sysconfig/network-scripts/ifcfg-eth0 里的文件.有的是(ifcfg-ens33) 文件 CentOS下的i ...

  2. SparkRDD内核

    Spark内核 RDD是基础,是spark中一个基础的抽象,是不可变的,比如我们加载进的数据RDD,如果想更改其中的内容是不允许的:分区的集合,可以并行来计算:RDD类中包含了很多基础的操作,例如ma ...

  3. Java -- 封装访问控制级别,包, instanceof 运算符, 初始化块

    1. 可以用 package name1.name2; 显式的定义包名, *.class文件位置应该对应包 name1 name2 的目录下. 2. instanceof 运算符 Object obj ...

  4. Spark-Spark setMaster & WordCount Demo

    Spark setMaster源码 /** * The master URL to connect to, such as "local" to run locally with ...

  5. Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】

    题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1 ...

  6. 分享知识-快乐自己:mongodb 安装部署(linux)

    1):下载 mongodb 包 [root@admin tools]# wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6. ...

  7. linux命令学习笔记(17):whereis 命令

    whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和 源代码文件(参数-s).如果省略参数,则返回所有信息. 和find相比,whereis查找的速度 ...

  8. 【leetcode刷题笔记】Longest Consecutive Sequence

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  9. 基于FTP服务、JAVA实现文件同步操作

    package lixj.ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStre ...

  10. 影响Cache的几个HTTP头信息【转载http://hi.baidu.com/feilala_fly/item/f79eca08fbf389026c9048a7】

    Http的Cache机制总共有4个组成部分: Cache-Control.Last-Modified(If-Modified-Since).Etag(If-None-Match) .Expires 服 ...