Visual Studio 2017 - инструмент Diagostic - профилирование кучи влияет на потребление памяти программой - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь отладить странную утечку памяти в приложении C # (использует c ++ / cli и c ++) с помощью инструмента диагностики и снимков памяти.Но я обнаружил одну странную проблему.

Когда я запускаю отладку в VS2017 с включенным профилированием кучи, потребление памяти остается постоянным, и программа работает, как и ожидалось.Когда профилирование кучи выключено, программа пропускает память, которая имеет линейное увеличение.Выполненная работа такая же, у меня есть прогресс работы, напечатанный на консоли, и я уверен, что обе программы выполнили одну и ту же работу, но одна использует постоянную память, а другая имеет линейно увеличивающуюся память (когда та же самая работа сделана, 2x использованная память).Визуально это выглядит так, что когда GC запускается с помощью профилирования кучи, освобождается какая-то память, а при использовании профилирования кучи память не освобождается.

Кто-нибудь знает, как это может повлиять на профилирование кучи?Утечка в основной памяти.

[EDIT1] Данные из Performance Profiler -> Использование памяти

Object Type Reference Count Module  
shared_ptr_cli<GeoAtomAttributes>       TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Finalization Handle] 856,275 TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Local Variable]  1   TestBackEnd64.dll
GeoAtomAttributesCli [Local Variable]   1   TestBackEnd64.dll

1 Ответ

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

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

Другие соображения;

Gc работает в управляемой куче, собственные библиотеки выделяют память в собственной куче.Так что это не может повлиять на управление памятью нативных библиотек.Но вы должны знать о следующих случаях. (Хотя это может быть и не ваш случай)

Если вы передаете закрепленные структуры данных в собственный код и free , эти дескрипторыв вашем Object.Finalize методе (класса оболочки);в этом случае закрепленная память может быть собрана только тогда, когда класс-оболочка находится в очереди для финализации. Вызов функций очистки (*) собственного кода в методе finalize управляемого класса также может вызывать аналогичные случаи.Я думаю, что это плохие практики и не должны использоваться, вместо этого эти очистки должны быть сделаны как можно скорее.

(*) В этом случае может увеличиться общее потребление памяти процессом, даже если в управляемой куче нет необходимости в gc.

...