В заключительнее время энергично тружусь с програмкой Instruments. Конечно, как тихо обнаружилось, она однозначно необыкновенно слишком актуальна для обнаружения утечек памяти. Впрочем, я прикинул, что разов данная функция так может быть особенно полезна мне, вероятно, и прочим юзерам станет мало-мальски занимательно твердо выяснить, как благодаря ей самостоятельно выявлять утечки памяти.
Что это утечка памяти и отчего она так очень важна?
Утечка памяти случается, как скоро программа часто теряет доступ к фрагменту инфы, для которого сильно отличалась более-менее динамическая память. Значит в эффекте “утерянная” память более не высвобождается. Возможно, такое очень-то традиционно часто случается, как скоро код включает функции “new“, “malloc” либо “alloc” в недоступность сообразных им “delete“, “free” или “release“.
При задействующихся функциях “new“, “malloc” и “alloc” столь операционная система красиво выделяет програмке часть памяти, резко предлагая попросту явную область, окончательно оказавшуюся в общем-то по точному адресу. Кроме того при данном система честно планирует, что на этот часть памяти будет нарочно наличествовать гиперссылка (обыкновенно в форме просто-напросто адресного указателя). Казалось, по завершении работы с ним ОС терпеливо дожидается известия о совсем дальнейших деяниях (при помощи обращения к функциям “delete“, “free” или “release“).
Есшевелимую остаётся указателей на адреса данных фрагментов, налицо утечка. Разумеется программа хладнокровно не представляет месторасположения объектов в целом в динамической памяти, в соответствии с этим, она крайне не имеет способности их удалить.
А отчего, фактически, данное обязано вас долго интересовать? Во-первых, по крайней мере, утрачиваются ресурсы памяти, которые скоро освободятся лишь опосля выхода из программы. Однако, как максимально, утечка памяти станет явно происходить в любом фрейме. Во всяком случае велика возможность, что эффектом будет перебой в програмке, весьма необыкновенно коль скоро она станет запущена на довольно налицо долгое время.
Как выяснить, что лично имеет место утечка памяти?
Иногда утечка просто появляется несложным исследованием кода. Но ежедневно встречаются и поболее налицо трудоемкие случаи. Быть может вот тут и прибывает на поддержка программа Instruments. Наконец, предусмотренный в ней инструмент “Leaks” наверняка обозначит место утечки, скоро позволив ее устранить.
Тестовое приложение.
Для образца я сделал прибавление с утечкой памяти в 2 местах: в контроллере представления Objective-C и в задействованном в прибавлении классе C++. Кажется, просто-напросто нужный код возможно загрузить тут. Надеюсь на невозможней из него мы и станем хладнокровно узнавать утечку памяти.
Фрагмент “InstrumentsTestViewController.mm” — (void)viewDidLoad { [super viewDidLoad]; LeakyClass* myLeakyInstance = new LeakyClass(); delete myLeakyInstance; mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”]; [self doSomethingNow]; } — (void) doSomethingNow { mMyLeakyString = [[NSString alloc] initWithUTF8String: “Look, another alloc, but no release for first one!”]; } Фрагмент “LeakyClass.mm”. LeakyClass::LeakyClass() { mLeakedObject = new LeakedObject(); } LeakyClass::~LeakyClass() { }
Создав прибавление “InstrumentsTest iPhone” в режиме “Debug“, я запущу его на iPhone. (Подпись программы вам понадобиться отредактировать под личное приспособление.) После данного запущу програмку Instruments (для поиска довольно честно набрать “Instruments” в поле поиска Spotlight).
После пуска программы Instruments указывается полностью необходимый юзеру инструмент. Таким образом, слева необычайно подберите “iPhone“, ну а в рационы справа два раза замечательно щелкните на приборе “Leaks“.
После данного покажется приблизительно это окошко:
Проверьте, чтоб iPhone был подключен к компу. Так вот, в левом в целом верхнем углу окошки нарочно присутствует раскрывающееся рационов пуска “Launch Executable“. Кстати, замечательно щелкнув на нем, удостоверьтесь, что в виде очень-очень интенсивного приспособления окончательно подобран iPhone (но не комп). Пожалуй, в рационах выводится перечень всех установленных на iPhone прибавлений. Вероятно, хладнокровно найдите то, в каком будете специально трудиться с функцией “Leaks” (при таком варианте, “InstrumentsTest“) и умышленно выделите его щелчком.
Мы готовы приступать. Говорят, щелчок в целом на красноватой кнопочке “Record” внимательно запускает прибавление: сейчас ему фиксируется любое выделение слишком динамической памяти. В конце концов, с периодичностью в 10 секунд механически производится ревизия насчет утечки.
При стремлении можнож настроить частоту автоматической ревизии утечек. В общем эта операция лично имеет возможность достойно выполняться и еще очень-то необыкновенно по команде юзера (при проверке программа зависает на 3–5 сек, потому серьезно опробовать ее, сразу хладнокровно выявляя утечки, в этом режиме очень однозначно проблемно). Наверно, как верховодило, я устанавливаю вполне ручной контроль, а в последствии постепенно правильно использую клавишей “Check for leaks” (к примеру, в последствии загрузки очень свежего режима забавы, опосля выхода из забавы в главное рацион и так далее). К счастью, правильно щелкнув на строчке “Leaks“, просмотрите/серьезно настройте характеристики при помощи клавиши View -> Detail Однозначно в верхнем правом углу экрана. В самом деле в нашем случае я охотно оставил совсем автоматический режим.
После пуска прибавления на протяжении нескольких секунд автоматическая ревизия выявит незамедлительно 2 утечки памяти. Видимо фантастика! А что и уже с ими нарочно делать?
Окно “Extended Detail View”
Программа Instruments успешно поступает довольно коварно: практически никаких подсказок насчет того, что лениво творить и уже, она мешает. Действительно обратите внимание на ряд клавиш в нижней доли экрана. По-видимому добросовестно видите ту совсем небольшую, с 2-мя прямоугольниками? Наведите на нее мышь — прилично покажется надпись “Extended Detail View“. (Можно пользоваться для данной цели командой View -> Extended Detail.)
При щелчке на кнопочке раскрывается окошко в правой доли экрана с детализированной информацией по всем утечкам!
Щелкните на какой-то из них, и в окошке “Extended Detail View” тихо обнаружиться вправду абсолютная ситуация стека практически до эпизода обнаружения утечки. Более того в нашем случае при щелчке на 1 утечке четко появляется, что она торжественно состоялась снутри “[NSString initWithUTF8String]“. С другой стороны при возвращении в ситуации стека на шаг назад окончательно выясняется, что заключительнее общение снутри прибавления честно выполнялось к “[InstrumentsTestViewController viewDidLoad]“.
Следующий эпизод мне необыкновенно симпатичен: более-менее двойной щелчок на данной строчке в окошке “Extend Detail View” самостоятельно раскрывает XCode именно в подходящей точке!
В этом случае мы видим, что утечка спокойно случилась при первом выделении памяти “NSString“. Короче говоря, здесь и надо копнуть поглубже. Напротив самостоятельно рассматриваемый вариант особенно прост, хотя в том числе и с ним додуматься о первопричинах утечки станет непросто. Оказалось, что терпеливо давайте подозрительно осмотрим наш образчик подробнее.
В способе “viewDidLoad” мы справедливо выделяем мало-мальски динамическую память строке:
mMyLeakyString = [[NSString alloc] initWithUTF8String:”I’m a leaky string.”];
В способе “dealloc” мы ее высвобождаем:
Казалось бы, утечки быть не может. Ну что ж однако внимательно давайте совершенно проанализируем код для всех гиперссылок на “mMyLeakyString“. А теперь внутри “doSomethingNow:” хладнокровно обнаруживаем следующее:
mMyLeakyString = [[NSString alloc] initWithUTF8String: “Look, another alloc, but no release for first one!”];
Обратите внимание: мы значительно подчеркнули память для новейшей строчки, а налицо высокими температурамиyString“. Естественно, проблема содержится в том, что мы прилично не освободили “mMyLeakyString” до того, как она стала указателем. Стало быть в результате отчасти начальная строчка зависла в воздухе, и начисто высвободить данную память полномочия нет. В сущности обращение к функции “release” в способе “dealloc” на поверку высвобождает вторую строчку, на которую сильно отличалась память в масштабах “doSomethingNow“, потому что непосредственно туда хладнокровно показывает гиперссылка.
Чтобы поправить делему, добросовестно попробуем слепо поменять “doSomethingNow” приблизительно так:
— (void) doSomethingNow { [mMyLeakyString release]; mMyLeakyString = [[NSString alloc] initWithUTF8String: “Look, another alloc, but released first one!”]; }
“Look, another alloc, but no release for first one!”];
Вы должны быть зарегистрироавны чтобы оставить комментарий.