Принцип Работы Детекторов Утечки Памяти
Как на самом деле работают детекторы утечки памяти? Каковы основные понятия в целом? Можно взять C++ в качестве языка, чтобы объяснить это.
3 ответа:
есть несколько различных способов работы детекторов утечки. Вы можете заменить реализацию
malloc
иfree
с теми, которые могут отслеживать дополнительную информацию во время распределения и не связаны с производительностью. Это похоже на то, какdmalloc
строительство. В общем, любой адрес, которыйmalloc
ЭД, но неfree
'D это слил.основная реализация на самом деле довольно проста. Вы просто поддерживаете таблицу поиска каждого распределения и его номер строки и удалите запись, когда она будет освобождена. Затем, когда программа будет выполнена, вы можете перечислить всю утечку памяти. Трудная часть-это определение того, когда и где распределение должно было быть освобождено. Это даже сложнее, когда есть несколько указателей на один и тот же адрес.
на практике вам, вероятно, понадобится больше, чем просто номер одной строки, а скорее трассировка стека для потерянных распределений.
другой подход заключается в том, как отчет произведения, которые реализует виртуальную машину для отслеживания адресов и ссылок на память и связанного с бухгалтерией. Подход valgrind намного дороже, но и гораздо более эффективен, поскольку он также может рассказать вам о других типах ошибок памяти, таких как чтение или запись за пределами границ.
Valgrind по существу измеряет основные инструкции и может отслеживать, когда данный адрес памяти не имеет больше ссылок. Он может сделать это, отслеживая назначения адресов, и поэтому он может скажу вам не просто, что часть памяти была утеряна, но точно , когда он заблудился.
C++ делает вещи немного сложнее для обоих типов детекторов утечки, потому что он добавляет
new
иdelete
операторы. Техническиnew
может быть совершенно другой источник памяти, чемmalloc
. Однако на практике многие реальные реализации C++ просто используютmalloc
для реализацииnew
или есть возможность использоватьmalloc
вместо альтернативного подход.также языки более высокого уровня, такие как C++, как правило, имеют альтернативные способы выделения памяти более высокого уровня, такие как
std::vector
илиstd::list
. Основной детектор утечки сообщал бы о потенциально многих распределениях, сделанных режимами более высокого уровня отдельно. Это гораздо менее полезно, чем сказать, что весь контейнер был потерян.
здесь опубликована техническая статья о том, как работает наш инструмент CheckPointer.
в основном он отслеживает время жизни всех значений (куча и стек), а также их размеры в соответствии с их типами, определенными языком. Это позволяет CheckPointer находить не только утечки, но и доступы вне массива, даже для массивов в стеке, которые valgrind не будет делать.
в частности, он анализирует исходный код, чтобы найти все указатель использует. (Это довольно сложная задача просто сам по себе).
он отслеживает метаданные указателя для каждого указателя, состоящего из
- ссылка на метаданные объекта для выделенного кучей объекта или глобальной или локальной переменной orfunction, на которую указывает указатель и
- диапазон адресов (sub) объекта объекта, к которому в данный момент может обращаться указатель. Это может быть меньше, чем диапазон адресов весь объект; например, если вы берете адрес члена структуры, то инструментированный исходный код будет разрешать доступ к этому элементу только при использовании результирующего указателя.
Он также отслеживает вид и расположение каждого объекта, т. е. является ли это функция, глобальная, локальная или локальная переменная потока, выделенная куча памяти или константа строкового литерала:
- диапазон адресов объекта, к которому можно безопасно получить доступ, и
- для каждого указателя, хранящегося в куче объект или переменная, ссылка на метаданные указателя для этого указателя.
все это отслеживание выполняется путем преобразования исходного источника программы в программу, которая делает то, что делает исходная программа, и чередует различные процедуры проверки или обновления метаданных. Полученная программа компилируется и запускается. Если проверка метаданных завершается неудачно во время выполнения, обратная трассировка предоставляется с отчетом о типе сбоя (недопустимый указатель, указатель вне допустимых границ,...)
Это помечено C и C++, и никакая операционная система не упоминается. Этот ответ для Windows.
C
Windows имеет понятие виртуальной памяти. Любая память, которую может получить процесс, является виртуальной памятью. Это делается через VirtualAlloc () [MSDN]. Вы можете представить себе детектор утечки, чтобы поставить точку останова на этой функции, и всякий раз, когда он вызывается, он получает стек вызовов и сохраняет его где-то. Тогда он может сделать подобное для VirtualFree () [MSDN].
разница может быть идентифицирована и показана вместе с сохраненными стеками вызовов.
C++
C++ имеет другую концепцию: он берет большие блоки 64kb, которые он получает от VirtualAlloc() и разбивает его на более мелкие части, называемые кучей. Менеджер кучи C++ поставляется от Microsoft и предлагает новые методы HeapAlloc () [MSDN] и HeapFree () [MSDN].
тогда, вы могли бы сделать то же, что и раньше, но на самом деле, эта функция уже встроенная. Microsoft GFlags [MSDN] инструмент может включить отслеживание:
в этом случае он сохранит до 50 Мб информации о стеке вызовов для вызовов диспетчера кучи C++.
поскольку эти настройки также могут быть включены через реестр Windows, детектор утечки памяти может легко использовать его.
общее понятие
Как вы можете видеть, общая концепция заключается в отслеживании распределения и освобождения, сравнить их и показать стеки вызовов разницы.