Я использовал методологию , изложенную 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](https://i.stack.imgur.com/AAzxT.png)
Вы можете видеть, что после выполнения этого кода частные байты не возвращаются к исходному количеству, а байты во всех кучах примерно постоянны, что подразумевает есть часть неуправляемой памяти, которая не была освобождена .Несколько раз подряд выполняется одна и та же встроенная функция, что не приводит к дальнейшему увеличению максимального количества наблюдаемых частных байтов или неизданной памяти.Как только основное приложение C # (VoiceAttack) закрывает всю связанную память (включая память для приведенного выше кода) освобождается.Плохая новость заключается в том, что при нормальных обстоятельствах основное приложение может работать пользователь неограниченно долго, из-за чего выделенная память остается невыпущенной.
Для большей ясности я бросил этот же код в VS (с парой Thread.Sleep(5000)
, добавленной до и после блока using
для лучшего графического анализа) и создал исполняемый файл для отслеживания с помощью метода Performance Monitor,и результат тот же.Существует первоначальный скачок неуправляемой памяти для OpenFileDialog, и выделенная неуправляемая память никогда не возвращается к исходному значению.
Имеет ли смысл описанная выше методология отслеживания памяти и утечек?Если ДА, можно ли что-нибудь сделать, чтобы правильно освободить неуправляемую память?