Анализ утечек памяти и помощь - PullRequest
0 голосов
/ 14 декабря 2018

Я использовал методологию , изложенную Shivprasad Koirala , для проверки утечек памяти из кода, работающего внутри приложения 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");
}

enter image description here

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

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

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

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

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

0 голосов
/ 14 декабря 2018

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

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

...