Недавно я запустил разные тесты в приложении .net, чтобы увидеть, как можно уменьшить объем памяти. Я сталкивался с различными советами / рекомендациями, такими как удаление неуправляемых ресурсов, отмена регистрации событий, использование FREEZE на ресурсах xaml и т. Д., И все это имело смысл. О большинстве вещей уже позаботились, поэтому потребление памяти осталось прежним. Однако я выяснил, что каждое новое окно, которое никогда ранее не открывалось в текущем цикле, будет занимать немного больше памяти и никогда не вернет его обратно после закрытия окна.
Итак, я запустил GC.Collect () сразу после закрытия окна для отладки, но безуспешно.
В приложении было несколько окон с AllowsTransparency = true, поэтому я удалил атрибут и увидел большую разницу в памяти, примерно на 5 МБ меньше! Так что проблема осталась прежней.
Вот образец
C #
Window w;
bool isWindowOpen = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (!isWindowOpen)
{
w = new Window();
isWindowOpen = true;
// turn off the following two lines to see a noteable difference.
w.AllowsTransparency = true;
w.WindowStyle = WindowStyle.None;
//Even when the transparency is set to false, the memory increased by the new
//Window will never be returned. Try making the window a little bit heavier by
//adding a few buttons and combos and clicking them rapidly before closing the
//window.
w.Show();
}
else
{ w.Close(); isWindowOpen = false; GC.Collect();
//Console.WriteLine(GC.GetTotalMemory(true).ToString());
//Console.WriteLine(GC.CollectionCount(0).ToString());
}
}
Может ли какой-нибудь гуру CLR / WPF объяснить это? Нет ли абсолютно никакого способа заставить GC запускаться сразу после закрытия прозрачного окна, освобождая всю используемую память? Я понимаю, что GC может запускаться позже, когда это необходимо, но, в конце концов, диспетчер задач - это все, что получают клиенты, и есть также некоторые маньяки.