GC.Collect() и PerformanceCounter

Мой коллега убежден, что в реализации Oracle odp.net ado.net есть утечка памяти. Он написал тестовую программу для проверки этой теории и делает следующее после вызова dispose для каждого объекта, чтобы определить, сколько памяти освобождается:

PerformanceCounter p = new PerformanceCounter("Memory", "Available Bytes");

GC.Collect();
GC.WaitForPendingFinalizers();

float mem = p.NextValue();

Полученное значение производительности затем сравнивается со значением, полученным до удаления объекта. Даст ли это точные результаты?


person zaq    schedule 02.05.2012    source источник
comment
Вы пытались использовать ProcessExplorer для мониторинга использования памяти .NET и системной памяти в вашем процессе? Вы не указали, какой тип памяти утекает...   -  person GregC    schedule 02.05.2012
comment
Нет, это не то, как работает диспетчер памяти. После того, как он преодолел трудности с выделением пространства виртуальной памяти, он помещает освобожденные блоки обратно в список свободных блоков, готовый к повторному использованию позже.   -  person Hans Passant    schedule 02.05.2012
comment
Мы не знаем, какой тип памяти утекает, что является одной из причин проведения теста, чтобы подтвердить наличие проблемы. Мой вопрос заключается в том, чтобы подтвердить, является ли тест действительным.   -  person zaq    schedule 02.05.2012
comment
почему мы используем метод dispose()?   -  person Lijo    schedule 26.06.2014


Ответы (1)


Я думаю, что лучший способ сделать это — использовать GC.GetTotalMemory(true). Вы можете вызвать его перед выделением объекта, чтобы записать, сколько памяти было выделено тогда. Затем вы создаете свой объект, возможно, выполняете какую-то операцию над ним, удаляете его, проверяете, что на него нет ссылок (возможно, просто устанавливаете локальную переменную в null), а затем снова вызываете его.

Имейте в виду, что возвращаемое значение может быть не совсем точным, согласно документации, метод вернет:

Число, которое является наилучшей доступной аппроксимацией количества байтов, выделенных в настоящее время в управляемой памяти.

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

Конечно, это не поможет вам, если у объекта происходит утечка неуправляемой памяти.

Другой вариант — использовать профилировщик памяти, но это может быть излишним, если вы знаете, где именно может происходить утечка памяти.

person svick    schedule 02.05.2012
comment
Спасибо за идею о том, как лучше получить результаты. Означает ли это, что что-то не так с подходом, который я опубликовал? Почему это лучший подход? - person zaq; 05.05.2012
comment
Да, ваш подход неверен, прочитайте комментарий Ханса Пассанта. Когда среда CLR собирает мусор, она обычно не возвращает память обратно в систему, поэтому вы можете не увидеть никаких изменений в доступных байтах, даже если память фактически была освобождена. - person svick; 05.05.2012