Простой образец WPF вызывает неконтролируемый рост памяти

Вы можете использовать вид сзади

\b(?

Демо

13
задан Fionnuala 11 October 2008 в 23:20
поделиться

3 ответа

Я смог воспроизвести Вашу проблему с помощью кода, который Вы предоставили. Память продолжает расти, потому что объекты Холста никогда не выпускаются; профилировщик памяти указывает, что ContextLayoutManager Диспетчера держится за них всех (так, чтобы он мог вызвать OnRenderSizeChanged когда необходимый).

кажется, что простое обходное решение должно добавить

c.UpdateLayout()

до конца BuildCanvas.

Тем не менее примечание, что Canvas UIElement; это, как предполагается, используется в UI. Это не разработано, чтобы использоваться в качестве произвольной поверхности рисунка. Как другие комментаторы уже отметили, создание тысяч объектов Холста может указать на недостаток дизайна. Я понимаю, что Ваш производственный код может быть более сложным, но если он просто тянет простые формы на холсте, GDI +-based кодируют (т.е. Система. Рисование классов), может быть более соответствующим.

10
ответ дан 2 December 2019 в 00:47
поделиться

Редактирование 2: , Очевидно, не ответ, но была часть назад и вперед среди ответов и комментариев здесь, таким образом, я не удаляю его.

GC никогда не получает шанс собрать те объекты, потому что Ваш цикл и его вызовы блокирования никогда не заканчиваются, и поэтому насос сообщения и события никогда не получают их очередь. Если бы Вы использовали Timer какой-то так, чтобы сообщения и события на самом деле имели шанс обработать, Вы, вероятно, не были бы в состоянии съесть всю свою память.

Редактирование: следующее не съедает мою память, пока интервал больше, чем нуль. Даже если интервал является всего 1 Галочкой, пока это не 0. Если это 0, мы вернулись к бесконечному циклу.

public partial class Window1 : Window {
    Class1 c;
    DispatcherTimer t;
    int count = 0;
    public Window1() {
        InitializeComponent();

        t = new DispatcherTimer();
        t.Interval = TimeSpan.FromMilliseconds( 1 );
        t.Tick += new EventHandler( t_Tick );
        t.Start();
    }

    void t_Tick( object sender, EventArgs e ) {
        count++;
        BuildCanvas();
    }

    private static void BuildCanvas() {
        Canvas c = new Canvas();

        Line line = new Line();
        line.X1 = 1;
        line.Y1 = 1;
        line.X2 = 100;
        line.Y2 = 100;
        line.Width = 100;
        c.Children.Add( line );

        c.Measure( new Size( 300, 300 ) );
        c.Arrange( new Rect( 0, 0, 300, 300 ) );
    }
}
0
ответ дан 2 December 2019 в 00:47
поделиться

Обычно в.NET GC включается объектное выделение после пересечения определенного порога, это не зависит от насосов сообщения (я не могу предположить, что это отличается с WPF).

я подозреваю, что объекты Холста так или иначе базированы глубоко внутри или что-то. Если Вы делаете c. Дети. Ясный () прямо перед концами метода BuildCanvas, рост памяти замедляется существенно.

Так или иначе, как комментатор отметил здесь, такое использование элементов платформы довольно необычно. Почему Вам нужно столько Холстов?

1
ответ дан 2 December 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: