Вопрос

В моем приложении у меня есть много RichTextBox, которые создаются динамически во время выполнения. Я понял, что у приложения есть утечка памяти, которая вызвана элементами управления RichTextBox. Чтобы доказать утечку памяти из-за контроля, я написал следующий метод теста:

for (int i = 0; i < 3000; i++)
        {
            Control rich = new RichTextBox();
            pnl.Content = rich;
        }
GC.Collect();
GC.WaitForPendingFinalizers();

pnl - это ContentControl, который объявлен в коде Xaml.
Если вы запустите следующий код, вы увидите, что использование памяти быстро растет.

Есть идеи, как решить проблему? Я подумал о создании пула объектов, но это усложнило бы мое приложение, и я бы предпочел его избегать.

<Ч>

edit . Я добавил вызов сборщику мусора, чтобы продемонстрировать, что объекты не являются сборщиком мусора - нет никакого улучшения в использовании памяти с вызовом метода сбора GC и без него. Обратите внимание, что вызов rich.Dispose в цикле устраняет рост использования памяти.

Это было полезно?

Решение

Нашел это где-то в другом месте, и, похоже, это правильно с точки зрения моего тестирования.

  

Когда создается FlowDocument,   относительно дорогое форматирование   объекты контекста также создаются для   это в его StructuralCache. Когда ты   создать несколько FlowDocs в тесном   цикл, StructuralCache создается для   каждый FlowDoc. Давай ты позвонил   Gc.Collect в конце цикла,   в надежде восстановить память.   StructuralCache имеет финализатор   освобождает этот контекст форматирования, но   не сразу. Финализатор   эффективно планирует операцию   освободить контексты в   DispatcherPriority.Background.

Таким образом, RichTextBox (или FlowDocument) на всякий случай не протекает, просто ожидая очистки в фоновом потоке. Когда он запускается точно, кто знает. Хотелось бы, чтобы это только что реализовало метод dispose, который немедленно вызвал бы очистку.

Другие советы

Это не означает, что у вашего приложения есть утечка памяти, это означает, что ваше приложение использует много памяти . Это утечка, если элементы управления RichTextBox не освобождаются в какой-то момент после того, как они вышли из области видимости (обнаружение утечек памяти на управляемых объектах общеизвестно сложно и недоказуемо).

Распространенное заблуждение, что объект, выпадающий из области видимости, приведет к его сборке мусора. Это просто делает приемлемым для сбора. Теоретически объект никогда можно собирать до тех пор, пока приложение не завершится. Тот факт, что он увеличивается с RichTextBox , а не с другими элементами управления, не означает, что в RichTextBox есть утечка памяти, это просто означает, что он использует больше памяти экземпляр, чем другие элементы управления. Хотя эта информация может быть полезной, она не помогает при определении наличия утечки памяти.

У нас была та же проблема в winforms 2.0, и нам пришлось купить сторонний форматированный текстовый элемент управления. Я думаю, что Microsoft не удосужилась исправить это ...

Это исправило проблему для меня: http://blingcode.blogspot.com/2010/10 /memory-leak-with-wpfs-richtextbox.html

В основном добавьте два атрибута к каждому RichTextBox :) :)  IsUndoEnabled = & Quot; Ложные & Quot;

Относительно вашего редактирования:

Вы добавили вызовы GC после того, как цикл завершился и были созданы все 3000 RichTextBox .

Хотя я согласен с тем, что кажется странным, что предыдущий не освобождается в цикле, когда он заменяется новым, это настолько узкий цикл, что GC, вероятно, не получает шанса "сделать свое дело" ; до завершения цикла.

Не думаю, что это хорошая идея (но в тестовом коде все должно быть в порядке), но вы пытались переместить вызовы GC внутри цикла?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top