Анализ утечки памяти и запрошенная помощь

Я использовал методологию , изложенную Шивпрасад Коирала для проверки утечек памяти из кода, работающего внутри приложения C# (VoiceAttack). В основном это включает в себя использование монитора производительности для отслеживания частных байтов приложения, а также байтов во всех кучах и сравнения этих счетчиков, чтобы оценить, есть ли утечка и какой тип (управляемый/неуправляемый). В идеале мне нужно протестировать вне Visual Studio, поэтому я использую этот метод.

Следующая часть кода создает приведенный ниже профиль памяти (имейте в виду, что код имеет немного другой формат по сравнению с Visual Studio, потому что это функция, содержащаяся в основном приложении C#):

public void main()
{
    string FilePath = null;
    using (FileDialog myFileDialog = new OpenFileDialog())
    {
        myFileDialog.Title = "this is the title";
        myFileDialog.FileName = "testFile.txt";
        myFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
        myFileDialog.FilterIndex = 1;

        if (myFileDialog.ShowDialog() == DialogResult.OK)
        {
            FilePath = myFileDialog.FileName;
            var extension = Path.GetExtension(FilePath);
            var compareType = StringComparison.InvariantCultureIgnoreCase;
            if (extension.Equals(".txt", compareType) == false) 
            {
                FilePath = null;
                VA.WriteToLog("Selected file is not a text file. Action canceled."); 
            }
            else
                VA.WriteToLog(FilePath);
        }
        else 
            VA.WriteToLog("No file selected. Action canceled.");
    }
    VA.WriteToLog("done");
}

введите здесь описание изображения

Вы можете видеть, что после выполнения этого кода частные байты не возвращаются к исходному количеству, а байты во всех кучах примерно постоянны, что означает, что есть часть неуправляемой памяти, которая не была освобождена. Выполнение одной и той же встроенной функции несколько раз подряд не приводит к дальнейшему увеличению максимального количества наблюдаемых закрытых байтов или невысвобожденной памяти. Когда основное приложение C# (VoiceAttack) закрывается, вся соответствующая память (включая память для приведенного выше кода) освобождается. Плохая новость заключается в том, что при нормальных обстоятельствах основное приложение может оставаться запущенным пользователем неопределенно долгое время, в результате чего выделенная память остается невысвобожденной.

На всякий случай я добавил этот же код в VS (с парой Thread.Sleep(5000), добавленной до и после блока using для лучшего графического анализа) и создал исполняемый файл для отслеживания с помощью метода Performance Monitor, и результат тот же. Существует начальный скачок неуправляемой памяти для OpenFileDialog, и выделенная неуправляемая память никогда не возвращается к исходному значению.

Имеет ли смысл изложенная выше методика отслеживания памяти и утечек? Если ДА, можно ли что-нибудь сделать, чтобы правильно освободить неуправляемую память?


person Exergist    schedule 14.12.2018    source источник


Ответы (2)


Имеет ли смысл изложенная выше методология отслеживания памяти и утечек?

Нет. Не следует ожидать, что неуправляемая выделенная память (Private Bytes) всегда будет освобождаться. Например, у процессов есть неуправляемая куча, которая управляется для последующего распределения. А поскольку Windows может подкачивать вашу выделенную память, нет необходимости минимизировать выделенную память для каждого процесса.

person David Browne - Microsoft    schedule 14.12.2018
comment
Я думал, что Private Bytes относится к общей памяти, выделенной для приложения, а вы ссылаетесь на Private Bytes как на неуправляемую выделенную память. Являются ли они одним и тем же или мы смешиваем терминологию? - person Exergist; 14.12.2018
comment
Частные байты в этом контексте в основном такие же, как выделенная память. - person David Browne - Microsoft; 14.12.2018
comment
Итак, если я правильно вас понимаю, пока нет увеличения в распределении, мне не следует беспокоиться об этом выделении личных байтов? - person Exergist; 14.12.2018
comment
Правильный. Постоянное увеличение с течением времени является признаком ослабления памяти. - person David Browne - Microsoft; 14.12.2018
comment
Многое из того, чем я занимаюсь (ИМХО), не требует вникания во что-то сложное вроде dotTrace или ANTS, и знать, есть утечка или нет, мне сейчас полезно. Помимо моего неверного предположения, что неуправляемая память всегда должна быть полностью освобождена, оставшаяся часть вышеприведенной методологии все еще действительна? - person Exergist; 14.12.2018

Если повторные вызовы не увеличивают использование памяти, у вас нет утечки памяти, вы задержали инициализацию. Некоторые компоненты не инициализируются до тех пор, пока вы их не используете, поэтому использование ими памяти не учитывается при установлении базового уровня.

person manveti    schedule 14.12.2018