icsharpcode / AvalonEdit

The WPF-based text editor component used in SharpDevelop
http://avalonedit.net/
MIT License
1.85k stars 469 forks source link

MemoryLeak in net 462 #386

Open SuperStudio opened 1 year ago

SuperStudio commented 1 year ago

There seems to be a memory leak

This is my step:

  1. Pull the latest master branch, compile version 462, and run sample code
  2. Paste and then empty about 1M of text
  3. After try 10 times, the memory reaches 500MB

However, the text has been emptied at last, and the memory is still not recycled

Before image

After 10 minute

image

jogibear9988 commented 1 year ago

I don't know, but didn't avalonedit have a undo stack? maybe this keeps all in memory? and if there is one (wich i don't know atm), isn't there an api to clear?

SuperStudio commented 1 year ago

I don't know, but didn't avalonedit have a undo stack? maybe this keeps all in memory? and if there is one (wich i don't know atm), isn't there an api to clear?

However, even use TextDocument.UndoStack.ClearAll() not work.

The only way is that to set TextEditor = null and then new TextEditor() to let GC work itself

SuperStudio commented 1 year ago

I don't know, but didn't avalonedit have a undo stack? maybe this keeps all in memory? and if there is one (wich i don't know atm), isn't there an api to clear?

However, even use TextDocument.UndoStack.ClearAll() not work.

The only way is that to set TextEditor = null and then new TextEditor() to let GC work itself

set TextEditor = null and then new TextEditor() still cause MemoryLeak.

Sample Code:

private async void TryWithSetNull(object sender, RoutedEventArgs e)
{
    await Task.Run(async () => {
    for (int i = 0; i < 100; i++) {
        App.Current.Dispatcher.Invoke(() => {
            editor.Text = SampleText;
        });
        await Task.Delay(50);
        App.Current.Dispatcher.Invoke(() => {
            editor.Clear();
                    editor.ClearUndo(); // clear undo stack
            editorGrid.Children.Clear();
            editor = null;
            editor = CreateTextEditor();
        });

    }
    });
    button.IsEnabled = true;
}

public TextEditor CreateTextEditor()
{
    editor = new TextEditor();
    editor.BorderBrush = Brushes.Blue;
    editor.BorderThickness = new Thickness(1);
    editorGrid.Children.Add(editor);
    return editor;
}

// in TextEditor.cs
public void ClearUndo()
{
    TextDocument document = this.Document;
    document.UndoStack.ClearAll();
}