У нас есть определенный набор действий в нашем приложении C #, который заставляет ОЗУ продолжать расти, пока форма не закроется. Эта форма является долгосрочной, и некоторые пользователи не будут закрывать ее в течение всего дня.
По сути, форма frmRelationalSearch
вызывает форму frmCombinedSearch
для поиска человека, а форма frmCombinedSearch
возвращает человека обратно в форму frmRelationalSearch
после закрытия формы frmCombinedSearch
. Форма frmRelationalSearch
- это долгоживущая форма, в то время как форма frmCombinedSearch
, кажется, вызывает проблемы.
В целях тестирования я вручную добавил в GC.Collect()
и GC.WaitForPendingFinalizers()
каждый цикл поиска сотрудников, чтобы проверить, действительно ли это утечка памяти. Я понял, что форма frmCombinedSearch
действительно собирается GC и, вероятно, только долго живет из-за того, что находится в очереди финализатора. Чего я не понимаю, так это как решить проблему растущего использования оперативной памяти, не вызывая вручную GC.Collect()
и GC.WaitForPendingFinalizers()
в нашем коде, потому что это плохая практика.
Я подтвердил это с помощью профилировщиков памяти dotMemory и ANTS.
Как мне справиться с этим? В этом случае допустимо ли вызывать GC вручную?
Это код прямо сейчас:
private void btnSearch_Click(object sender, EventArgs e)
{
// Without these three lines, the RAM will continue to grow until
// this form (frmRelationalSearch) is closed.
// GC.Collect();
// GC.WaitForPendingFinalizers();
// GC.Collect();
frmCombinedSearch frm = new frmCombinedSearch();
try
{
// Custom code which just shows the form in the current tab
frm.ShowInTab(this.ParentTabPage);
}
catch (Exception ex)
{
this.ShowException(ex);
}
}
В обоих анализаторах frmCombinedSearch
сохраняется из-за очереди финализатора.
EDIT :
ShowInTab()
не является блокирующим, поэтому я не могу использовать оператор using
для его удаления, потому что он будет удален сразу после создания.