- Выявление утечек памяти в C++
- 1 Обнаружение утечек с библиотекой CRT
- 2 Использование Visual Leak Detector
- 3 Работа с Valgrind memcheck
- 4 Как это устроено внутри
- 4 Более сложный пример
- Как найти и исправить утечки памяти в Windows 10/8/7
- Утечки памяти в Windows 10
- Предотвращение утечек памяти
- Устранение утечек памяти в Windows
Выявление утечек памяти в C++
В работе участвовали:
Гильденберг Максим и Панкратов Семен
Утечка памяти достаточно серьезная проблема возникающая при работе программы. Масштабность проявляется особенно при длительной работе программы, когда программа может исчерпать лимит выделения для нее памяти, а это приведет к очень нехорошим последствиям.
Простейшая программа с утечкой памяти:
В данном участке кода утечка памяти происходит из-за отсутствия оператора delete[] для массива p.
В статье «Анализ программ и компиляторов в Compiler Explorer» показано, что в ряде случаев утечки памяти можно найти средствами статического анализа программ, однако такие инструменты нередко дают «ложные срабатывания», а иногда — не обнаруживают утечку.
В этой статье рассмотрены:
1 Обнаружение утечек с библиотекой CRT
Библиотека CRT доступна в операционной системе Windows, она у вас уже есть если вы используете Microsoft Visual Studio. Для подключения анализатора памяти достаточно добавить пару макросов и собрать проект в отладочном режиме:
Видно, что первая группа макросов добавляется в самое начало вашей программы. За счет этих макросов все обращения в функциям new, malloc, free и delete заменяются на другие версии, которые помимо выделения/освобождения памяти сохраняют дополнительную информацию (сколько и где было выделено). Макрос _CrtDumpMemoryLeaks добавляется в конец программы (перед завершением работы) и выводит информацию о текущем состоянии памяти.
Для приведенной выше программы в окно отладки будет выведено следующее:
Утечка была обнаружена, кроме того, нам показывают ее размер и даже строку кода где это случилось.
2 Использование Visual Leak Detector
VLD поставляется в виде плагина для Microsoft Visual Studio, для его установки:
1) Скачиваем с официального сайта Microsoft и устанавливаем.
2) Добавляем в свойствах проекта во «включаемые каталоги» путь к каталогу include:
C:\ProgramFiles(x86)\VisualLeakDetector\include .
3) Добавляем в свойствах проекта в Каталог библиотек для win32 или win64 : путь к катлогу lib:
4) Добавляем в начало главного файла ( main.cpp ) #include
Получается так:
Все говото, утечки ищутся и выводятся в консоль отладки:
Видно, что VLD выводит информацию о стеке вызовов, но формат вывода крайне неудобный. Узнать в какой строке произошла утечка памяти совсем непросто.
3 Работа с Valgrind memcheck
Valgrind предоставляет множество инструментов для динамического анализа, поиском утечек памяти это не ограничивается. Работой с памятью занимается модуль memcheck. Для его использования необходимо:
1) Сстановить valgrind:
sudo apt install valgrind
2) Скомпилировать программу в debug-режиме и запустить ее через valgrind:
valgrind ./my_program
При таком запуске будет выведено сколько памяти было потеряно. Чтобы увидеть, где была выделена память, необходимо добавить опцию
—leak-check=full .
Результаты работы memcheck для нашего примера:
4 Как это устроено внутри
Подключение CRT приводит к оборачиванию функций работы с памятью в что-то такое:
Вы могли бы сделать это сами, но это непросто, а ведь надо еще разобрать все возможные ошибки при работе с памятью — free вместо delete , выделение объекта одного типа, а удаление — другого и так далее.
Да и зачем этим заниматься если его готовый CRT? В свою очередь, Visual Leak Detector представляет собой обертку над CRT.
Утилита Valgrind работает совсем иначе — ей не требуется модифировать исходный код вашей программы. Вместо этого программа запускается на виртуальном (моделируемом) процессоре в виртуальном окружении. Это окружение точно знает сколько памяти потребила программа, а процессор — в каких инструкциях эта память была запрошена. За счет этого valgrind позволяет не только обнаружить утечки памяти, но и получить статистику кэш-попаданий (модуль cachegrind), например. Однако, тут внутреннее устройство valgrind показано крайне упрощенно, а на самом деле все гораздо сложнее. Тем не менее, это один из лучших инструментов поиска утечек в мире.
4 Более сложный пример
Возможно, вам кажется что проблем с поиском утечек не возникает, тогда посмотрите такой пример:
Сколько времени у вас уйдет на поиск всех утечек? Ведь после возврата строки delete p в программе появятся другие утечки. Для начала — не будет вызывать деструктор
Cat() ведь деструктор
Animal() объявлен невиртуальным. После исправления этой ошибки — мы получим еще одну, ведь в классе Cat память выделяется через new , а освобождается через free .
Результаты применения всех трех рассмотренных инструментов примерно одинаковы (разве что VLD не выводит информацию о строке возникновения ошибки). Ниже приведен вывод valgring memcheck:
Видно, что обнаруживается 3 утечки, так как на 3 аллокации не приходится ни одной операции освобождения. После добавления delete в функцию main получаем одну утечку. Теперь на 3 аллокации приходится две операции освобождения. Найдена лишь одна утечка, однако на самом деле — вообще не вызывается деструктор
Cat() , поэтому после замены free на delete в нем — результат работы не изменится. А вот после добавления виртуального деструктора — утечек найдено не будет.
Понятно, что описанные инструменты сильно упрощают жизнь программисту. Найти без них течки памяти в чужом коде из 10 тысяч строк кода — задача крайне сложная, а с ними — решается элементарно. Однако, вывод результатов их работы очень неинформативный. Сравните полученные результаты с выводом статических анализаторов (в обоих статьях используются одинаковые примеры).
Источник
Как найти и исправить утечки памяти в Windows 10/8/7
Утечка памяти – это неправильное размещение ресурса в компьютерной программе из-за неправильного распределения памяти. Это происходит, когда неиспользуемая область ОЗУ остается невыпущенной. Утечку памяти не следует путать с утечкой пространства, которая относится к программе, использующей больше оперативной памяти, чем необходимо. Утечка памяти в системе Windows 10/8/7, как говорят, произошла, когда память просто недоступна, несмотря на то, что она не используется.
Утечки памяти в Windows 10
Прежде чем начать, вы должны знать, что утечка памяти – это проблема программного обеспечения для отладки – например, в Java, JavaScript, C/C ++, Windows и т. Д. Физическая замена ОЗУ или жесткого диска не требуется.
Почему это плохо
Очевидно, что утечка памяти – это плохо, потому что это ошибка, недостаток в системе. Но давайте выясним, как именно это влияет на систему:
- Поскольку память не освобождается, даже когда она не используется, это приводит к ее истощению.
- Исчерпание памяти приводит к старению программного обеспечения.
- Уменьшение доступной памяти приводит к увеличению времени отклика и снижению производительности системы.
- Неконтролируемая утечка памяти может в конечном итоге привести к сбою приложения.
Чтобы идентифицировать утечку памяти, программист должен иметь доступ к исходному коду программы.
Обнаружение утечки
Чтобы решить проблему, нам нужно сначала ее идентифицировать. Основные шаги по обнаружению утечки памяти:
- Подтверждение . Определение наличия утечки.
- Поиск утечки памяти в режиме ядра . Поиск утечки, вызванной компонентом драйвера режима ядра.
- Поиск утечки памяти в пользовательском режиме . Поиск утечки, вызванной драйвером пользовательского режима или приложением.
Распределение памяти
Существуют разные режимы, в которых приложения выделяют оперативную память. Если пространство не освобождается после использования, утечка памяти будет происходить независимо от режима выделения. Некоторые общие шаблоны распределения:
- Функция HealAlloc для выделения кучи памяти. Эквивалентами времени выполнения C/C ++ являются malloc и новые.
- Функция VirtualAlloc для прямого выделения из ОС.
- Kernel32 API для хранения памяти ядра для приложения. Пример, CreateFile, CreateThread.
- User32 API и Gdi32 API.
Предотвращение утечек памяти
Мы все знаем, что профилактика лучше лечения, поэтому есть несколько способов предотвратить утечку памяти.
Мониторинг привычек
Вы должны следить за ненормальным использованием ОЗУ отдельными программами и приложениями. Вы можете перейти в диспетчер задач Windows, нажав CTRL + SHIFT + ESC и добавить такие столбцы, как дескрипторы, объекты пользователя, объекты GDI и т. Д.
Это поможет вам легко отслеживать использование ресурсов.
Инструменты Microsoft для диагностики утечек памяти
Различные инструменты диагностируют утечки памяти для различных режимов выделения:
- Верификатор приложения диагностирует утечки кучи.
- UMDH (компонент средств отладки Windows) диагностирует утечки для отдельных процессов, отслеживая выделение кучи памяти.
- Trace Capture для тщательного анализа использования оперативной памяти.
- Xperf также отслеживает шаблоны распределения кучи.
- CRT Debug Heap не только отслеживает выделение кучи, но также позволяет использовать методы кодирования для минимизации утечек.
- JavaScript Memory Leak Detector отлаживает утечки памяти в кодах.
Советы по использованию
- Используйте ядра HANDLE и другие умные указатели для ресурсов Win32 и выделения кучи.
- Получите классы для автоматического управления ресурсами для выделения ядра из библиотеки ATL. Стандарт C ++ имеет auto_ptr для распределения кучи.
- Инкапсулируйте указатели COM-интерфейса в «умные указатели» с помощью _com_ptr_t или _bstr_t или _variant_t .
- Мониторинг кода .NET на предмет ненормального использования памяти.
- Избегайте множественных путей выхода для функций, чтобы к концу функции освободить выделения из переменных в большинстве блоков.
- Используйте собственные исключения только после освобождения всех выделений в блоке _finally. Оберните всю кучу и обработайте выделения в интеллектуальные указатели, чтобы использовать исключения C ++.
- Всегда вызывайте функцию PropVariantClear перед повторной инициализацией или удалением объекта PROPVARIANT.
Устранение утечек памяти в Windows
Так же, как различные способы предотвращения утечек памяти, существуют различные способы остановить утечки памяти.
1] Закройте процессы и перезапустите.
Если вы видите, что ненужный процесс занимает слишком много ОЗУ, вы можете завершить процесс в диспетчере задач. Вам нужно будет перезагрузить устройство, чтобы освободившееся пространство было доступно для использования другими процессами. Без перезагрузки проблема утечки памяти не будет решена. Одним из конкретных процессов, которые имеют ошибки для замедления работы ПК, является Runtime Broker. Попробуйте, если отключение, которое само по себе работает.
2] Инструменты диагностики памяти
Чтобы получить доступ к встроенному инструменту диагностики памяти для Windows:
- Сохраните всю вашу важную работу.
- Нажмите Win + R , чтобы открыть окно Выполнить .
- Введите команду mdsched.exe в окне Выполнить .
- Перезагрузите компьютер.
- После перезапуска выполните базовое сканирование или выберите параметры Расширенные , например Test mix ’или Количество проходов ’.
- Нажмите F10 , чтобы начать тестирование.
Это все еще временные исправления.
3] Проверить обновления драйверов
Устаревшие драйверы вызывают утечки памяти. Держите все драйверы обновленными:
- Нажмите Win + R и откройте окно Выполнить . Введите devmgmt.msc и нажмите Enter. Вы попадете в Диспетчер устройств .
- Проверьте устаревшие драйверы и обновите их все.
- Для обновлений, которые вы могли пропустить, проверьте в Центре обновления Windows.
Это было просто.
4] Оптимизация производительности
Настройка Windows на производительность будет управлять всем, включая планирование процессора и использование памяти, чтобы предотвратить утечки памяти. Следуй этим шагам:
- Нажмите правой кнопкой мыши на Этот компьютер ’и выберите настройки Дополнительно на левой панели.
- На вкладке “ Дополнительно ” перейдите в раздел “ Эффективность “, а затем “ Настройки “.
- Установите флажок Настроить для лучшей производительности и нажмите ОК .
- Перезапустите и проверьте, решена ли проблема.
Если это простое решение не сработало, попробуйте следующее решение.
5] Отключить программы, запускаемые при запуске
Отключение проблемных программ – единственный способ избавиться от проблемы утечки памяти. Зайдите в диспетчер задач и отключите программу, создающую проблемы. Если вы не знаете, какие программы создают проблемы, сделайте следующее:
- Перейдите в Диспетчер задач .
- Перейдите в “ Запуск “.
- Отключите автозапуск программ, которые вам не нужно запускать по умолчанию.
6] Дефрагментация жесткого диска
Хотя Windows 10 делает это для вас автоматически, вам может понадобиться время от времени выполнять дефрагментацию жестких дисков для оптимизации производительности:
- Перейдите на страницу “ Этот компьютер ” или “ Мой компьютер “.
- Щелкните правой кнопкой мыши системный жесткий диск (обычно диск C:).
- Перейдите на вкладку Инструменты и выберите Свойства ‘и выберите Оптимизировать ’.
- Выберите диск для дефрагментации и выберите « Анализировать ».
Перезагрузите компьютер после новой фрагментации.
7] Файл ClearPage при завершении работы
Сейчас становится все сложнее, но не волнуйтесь. Вот как очищать файл подкачки при каждом выключении:
- Введите regedit в поле поиска, чтобы запустить редактор реестра.
- Введите этот путь: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlSession ManagerMemory Management
- Измените значение ClearPageFileAtShutDown на «1».
- Сохраните изменения и перезагрузите устройство.
Это должно сделать это.
9] Отключить суперпатч
Этот сервис Windows оптимизирует производительность за счет минимизации времени загрузки. Это позволяет Windows управлять использованием оперативной памяти. Жизнь после отключения Superfetch не удобна, но сделайте это, если нужно. По крайней мере, попробуйте это в одиночку, чтобы изолировать проблему:
- Найдите services.msc и перейдите в диспетчер служб.
- Найдите Superfetch и нажмите его правой кнопкой мыши, чтобы перейти в Свойства .
- Выберите « Стоп ».
- Также Отключить ’сервис из раскрывающегося меню.
- Перезагрузите компьютер и проверьте, не улучшилась ли производительность.
Включите Superfetch, если этот не работает.
10] Проверка на наличие вредоносных программ
Используйте стороннее антивирусное программное обеспечение или встроенный в Windows 10 Защитник Windows для сканирования и устранения вредоносных программ.Убедитесь, что антивирус обновлен для поддержки вашей ОС, чтобы он не стал причиной утечки памяти.
Каждое решение, которое вам когда-либо понадобится, чтобы найти или предотвратить утечку памяти, находится здесь. Вы можете прочитать больше об утечках памяти на MSDN и Microsoft.
Источник