TextBox: Major memory leak in WPF
Andre from Microsoft wrote in December 2007:
We recently found out about a couple memory leaks.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2511874&SiteID=1&pageid=0
Sadly, there is another, major one: The WPF Textbox is leaking memory everytime one changes the Text property.
You can try it like this:
Put a textbox into a WPF window
Continue to change the TEXT property
See in the perfomancemonitor how the memory consumption grows and grows and grows ...
Here is the code:
Code Snippet<
Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="Auto" Width="Auto" SizeToContent="WidthAndHeight" WindowStyle="ToolWindow"> <StackPanel Orientation="Vertical"> <Label>TextBox</< FONT>Label> <TextBox x:Name="textBox"/> </< FONT> </STACKPANEL< FONT>></< FONT></WINDOW< FONT>>
Code Snippetusing System.Windows;
namespace
WpfApplication1 {public partial class Window1: Window {
public Window1() {
InitializeComponent();
this.Loaded += Window1_Loaded;
}
void Window1_Loaded(object sender, RoutedEventArgs e) {
bool isToggle = false;
while (true) {
if (isToggle) {
textBox.Text = "a";
isToggle = false;
} else {
textBox.Text = "b";
isToggle = true;
}
}
}
}
}
To prove that the problem is caused by the Text property, change the above code like this
Code Snippetif (isToggle) {
textBox.Text =
"a";isToggle =
false;}
else {textBox.Text =
"a";isToggle =
true;}
The performance monitor shows now that there is no memory increase anymore.
Comment
If only .NET and Visual Studio would provide better tools to test and analyze memory leaks, I am sure Microsoft would create fewer of them. Somehow Microsoft seems to think that Garbage Collection is a miracle weapon and makes it behave like a black box. But unfortunately, we developers have plenty of possibilities to leak memory, but only stone age tools to investigate them.
Answers
i could repro this issue.. we are tracking this as a bug..
Thanks for reporting.
replied on the wrong thread
I've confirmed this is the designed behavior of TextBox.
We allocate for the undo stack whenever text changes.
One of the ways this behavior can be turned of is to set the TextBox.UndoLimit to a low number;
--Ifeanyi Echeruo [MSFT]
All Replies
Sounds like a good opportunity to try stepping into the .NET source code...
-Jer
- I wonder if anyone can confirm my findings ? I can hardly believe that Microsoft didn't notice such a fundamental memory leak. On the other hand, my test code is trivial and the memory consumption goes straight through the roof.
I tested your code with a minor modification
textBox.UndoLimit = 0;
I think the leak was TextBox building an undo stack for all the text changes.
Code below
Code Snippetnamespace WpfApplication1 {
using System;
using System.Windows;
using System.Windows.Controls;
public class Program {
static TextBox textBox;
[STAThread]
static void Main() {
Application app = new Application();
Window w = new Window();
textBox = new TextBox();textBox.UndoLimit = 0;
w.Loaded += Window1_Loaded;
w.Content = textBox;
w.Show();
app.Run();
}
static void Window1_Loaded(object sender, RoutedEventArgs e) {
bool isToggle = false;
while (true) {
if (isToggle) {
textBox.Text = "a";
isToggle = false;
} else {
textBox.Text = "b";
isToggle = true;
}
}
}
}
}--Ifeanyi Echeruo [MSFT]
i could repro this issue.. we are tracking this as a bug..
Thanks for reporting.
replied on the wrong thread
I've confirmed this is the designed behavior of TextBox.
We allocate for the undo stack whenever text changes.
One of the ways this behavior can be turned of is to set the TextBox.UndoLimit to a low number;
--Ifeanyi Echeruo [MSFT]
True, to use an unlimited amount of memory is by design, as the help says:
TextBoxBase.UndoLimit Property: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.
But I wonder how many developers are aware of that behavior. In our case, the application is supposed to run for a year or longer and we update the textbox several times per second to display measurement results. To us, the behavior of the textbox with default properties certainly looked like a memory leak.
Thanks for the fast support.
Your scenario is one we expected to be addressed by TextBlock or Label.
TextBox pulls in extra editing services like IME, spell checking and undo.
Is there a specific reason you are using TextBox instead?
--Ifeanyi Echeruo [MSFT]
When we realised that there is a "memory leak" in the text box, but we didn't know how to stop it, we replaced the textboxes with labels. But the textbox has some advantages, like when they stop the measurement, they can select the text in the text box and copy it, which is not possible with a label.
Actually, we face this situation quiet often, that we display something to the user, like an error message. We don't want him to change what we display, but he should be able to select the text and copy it. But most of the time Windows Forms and WPF don't allow the user to select and copy text from the GUI, as opposed to a Web-Page.
How many times did I hava to retype Windows OS error messages just to get support.
- This is really interesting.... I created a blog post for it
http://marlongrech.wordpress.com/2008/02/16/wpf-textbox-memory-leak/ - How can I (or what tool can I use) to track or measure performance like this using VS 2008?
There are performance tools that come with some SKU's of Visual Studio
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=339481&SiteID=1
Has a bunch of links to get you started.
There are a couple more standalone tools from MS
http://search.live.com/results.aspx?q=clrprofiler
There are also a few very good 3rd party tools
http://search.live.com/results.aspx?q=.net+memory+profiler
http://search.live.com/results.aspx?q=.net+performance+tools
--Ifeanyi Echeruo [MSFT]
my two cents. Would be good to set this in application resources - http://infosysblogs.com/microsoft/2008/03/wpf_textbox_memory_leak_issue_1.html- atul's solution will not work... local style will override style's from app.resources
- to jofrpl:atul's solution works.

