понедельник, 7 июня 2010 г.

Поиск утечек памяти для бедных

Это перевод The poor man's way of identifying memory leaks. Автор: Реймонд Чен.

Существует множество различных утилит, способных помочь в поиске утечек ресурсов, но есть один метод, который не требует утилит, специальных настроек компилятора или библиотек поддержки: просто позвольте утечкам расти, пока их источник не станет очевиден.

Ночные автоматические стресс-тесты являются обычной частью любого проекта. Некоторые команды используют в качестве пускалки хранитель экрана, другие - ручной запуск по требованию, но как бы там ни было, после того, как вы уйдёте домой, ваша машина подключится к центральному серверу и получит набор тестов, которыми она будет заниматься всю ночь.

Одной из вещей, которые часто выявляют эти ночные тесты, являются утечки памяти различного рода, они находятся во время стресс-тестирования, потому что использование ресурсов вашей программой стало необычно высоко. Но как вы будете отлаживать их? На машинах не запущено никаких специальных инструментов или ваших любимых утилит по поиску утечек памяти, так что вы не сможете их использовать.

Вместо этого, вы воспользуетесь принципом "target-rich environment".

Предположим, что у вас утекает память. После пятнадцати часов непрерывной работы ваша программа начинает получать ошибки out-of-memory. Очевидно, что вы где-то протекаете, но где?

Подумайте об этом: если у вас что-то утекает, то этого что-то сейчас должно быть уже много. А вещи, которые не утекают - их должно быть мало. Поэтому, если вы возьмёте указатель наугад, то почти наверняка это будет утёкший объект! В математических терминах: предположим, что нормальное использование вашей программы требует 15 мегабайт памяти, но по какой-то причине сейчас вы занимаете 1693 мегабайт памяти. Поскольку только 15 мегабайт из этого количества памяти являются вашими актуальными данными, то остальные 1678 мегабайт должны быть заняты утечками. Если вы ткнёте в эту память наугад, то у вас будет шанс-лучший-чем-99%, что вы ткнёте в утёкший объект.

Так что возьмите дюжину адресов наудачу и проанализируйте их. Скорее всего, вы увидите один и тот же шаблон данных снова и снова и снова. Это ваша утечка. Если это Delphi-объект с динамическими/виртуальными методами, то чтение его VMT поможет вам понять, что это за объект. Если же это простой тип данных, то обычно вы можете идентифицировать его, смотря на содержимое строк или указателей на другие данные.

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

3 комментария:

  1. Звучит очень логично. А как взять и проанализировать наугад указатель, если программа запущена не из делфей?
    Подключиться потом к ней дебаггером?

    ОтветитьУдалить
  2. Да, можно подключится отладчиком, можно написать спец. утилиту для этого (как я сделал это для анализа зависаний), а можно подготовиться к такой ситуации заранее и плюхнуть кнопку на форму "Сдампить всю память в файл". Короче, всё ограничено только вашей фантазией.

    ОтветитьУдалить
  3. > Короче, всё ограничено только вашей фантазией.
    И квалификацией. =)

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.