Средство застрявшего заклинивает, завершает работу без вызова GC вручную - PullRequest
0 голосов
/ 03 января 2019

У нас есть определенный набор действий в нашем приложении 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 для его удаления, потому что он будет удален сразу после создания.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

frmCombinedSearch и frmRelationalSearch одноразовые?Если это так, вы можете реализовать использование так, чтобы он собирался после закрытия.

примерно так:

using(frmCombinedSearch frm = new frmCombinedSearch()){
    try {
       frm.ShowInTab(this.ParentTabPage); }
    catch(Exception ex) {
       this.ShowException(ex); } }
0 голосов
/ 03 января 2019

WinForms должны быть закрыты или удалены ( ссылка ).Я рекомендую использовать using.

private void btnSearch_Click(object sender, EventArgs e)
{
    using (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);
        }
    }
}
...