Как избежать, найти и устранить утечки памяти в какао - PullRequest
19 голосов
/ 05 октября 2008

случаются утечки памяти (и ресурсов). Как вы убедитесь, что они не делают?

Какие советы и приемы вы бы предложили, чтобы избежать утечек памяти?

Если у вас есть приложение с утечками, как вы можете отследить источник утечек?

(О, и, пожалуйста, избегайте ответа «просто используйте ГХ». Пока iPhone не поддерживает ГХ, это неправильный ответ, и даже в этом случае возможна утечка ресурсов и памяти в ГХ)

Ответы [ 9 ]

21 голосов
/ 05 октября 2008

В XCode 4.5 используйте встроенный Статический анализатор .

В версиях XCode до 3.3 вам, возможно, придется загрузить статический анализатор. Эти ссылки показывают, как:

Использование статического анализатора LLVM / Clang

Во-первых, чтобы избежать утечек памяти, используйте Clang Static Analyzer , чтобы - что неудивительно - анализировать ваш код C и Objective-C (пока еще нет C ++) в Mac OS X 10.5. Установить и использовать тривиально:

  1. Загрузите последнюю версию с этой страницы .
  2. Из командной строки cd в каталог вашего проекта.
  3. Выполнить scan-build -k -V xcodebuild.

(Есть некоторые дополнительные ограничения и т. Д., В частности, вы должны проанализировать проект в его конфигурации «Отладка» - подробности см. http://clang.llvm.org/StaticAnalysisUsage.html - но это более или менее сводится к тому, что сводится к следующему). к.)

Затем анализатор создает для вас набор веб-страниц, которые показывают вероятное управление памятью и другие основные проблемы, которые компилятор не может обнаружить.

Если ваш проект не ориентирован на рабочий стол Mac OS X, есть пара других деталей:

  1. Установите для базового SDK для всех конфигураций SDK, в котором используются каркасные платформы Mac OS X ...
  2. Настройте сборку командной строки на использование конфигурации отладки.

(Это в значительной степени тот же ответ, что и на этот вопрос .)

16 голосов
/ 05 октября 2008

Не забывайте об управлении памятью

По некоторым причинам многие разработчики (особенно на ранних этапах) делают управление памятью более трудным для себя, чем когда-либо, часто из-за переосмысления проблемы или воображения, что она более сложна, чем она есть.

фундаментальные правила очень просты. Вы должны сосредоточиться только на том, чтобы следовать за ними. Не беспокойтесь о том, что могут делать другие объекты или каков счет вашего объекта. Поверьте, что все остальные соблюдают тот же контракт, и все это будет просто работать.

В частности, я еще раз повторю мысль о том, что не стоит беспокоиться о сохранении количества ваших объектов. Сам счет удержания может вводить в заблуждение по разным причинам. Если вы обнаружите, что регистрируете счет сохранения объекта, вы почти наверняка идете по неверному пути. Отойдите назад и спросите себя, соблюдаете ли вы фундаментальные правила?

10 голосов
/ 05 октября 2008

Всегда используйте методы доступа; объявить методы доступа, используя свойства

Вы значительно упростите себе жизнь, если будете всегда использовать методы доступа для присвоения значений переменным экземпляра (кроме методов init* и dealloc). Помимо обеспечения надлежащего запуска любых побочных эффектов (например, уведомлений об изменениях KVO ), значительно снижается вероятность того, что вы столкнетесь с копией-вставкой или какой-либо другой логической ошибкой, чем если бы вы посыпьте ваш код retain с и release с.

При объявлении методов доступа всегда следует использовать функцию Objective-C 2 . Объявления свойств делают семантику управления памятью аксессорами явной. Они также предоставляют вам простой способ перекрестной проверки с помощью метода dealloc, чтобы убедиться, что вы освободили все свойства, объявленные вами как retain или copy.

8 голосов
/ 05 октября 2008

Инструмент Instruments Leaks очень хорошо подходит для обнаружения утечек памяти определенного класса. Просто используйте пункт меню «Начать с Performance Tool» / «Утечки», чтобы автоматически запустить ваше приложение через этот инструмент. Работает для Mac OS X и iPhone (симулятор или устройство).

Инструмент "Утечки" помогает вам найти источники утечек, но не помогает в такой степени отследить, где хранится утечка памяти.

6 голосов
/ 05 октября 2008
  • Следуйте правилам хранения и выпуска (или используйте сборщик мусора). Они обобщены здесь .

  • Используйте инструменты для отслеживания утечек. Вы можете запустить приложение в разделе Instruments, используя Build> Start With Performance Tool в Xcode.

2 голосов
/ 05 октября 2008

Я помню, как использовал инструмент Omni некоторое время назад, когда пытался отследить некоторые утечки памяти, которые бы отображали все вызовы retain / release / autorelease для объекта. Я думаю он показал трассировки стека для распределения, а также все сохранения и освобождения объекта.

http://www.omnigroup.com/developer/omniobjectmeter/

1 голос
/ 25 декабря 2008

Вы можете построить бета-порт Valgrind отсюда: http://www.sealiesoftware.com/valgrind/

Он гораздо полезнее любого статического анализа, но пока не имеет никакой специальной поддержки Какао, о которой я знаю.

1 голос
/ 06 октября 2008

Прежде всего, крайне важно, чтобы использование скобок и скобок [] и {} соответствовало универсальному стандарту. ОК, просто шучу.

Рассматривая утечки, вы можете предположить, что утечка связана с проблемой в вашем коде, но это не 100% ошибки. В некоторых случаях может быть что-то происходящее в коде Apple (задыхаясь!), Который виноват. И это может быть что-то, что трудно найти, потому что это не отображается как объекты какао. В прошлом я сообщал об ошибках в Apple.

Утечки иногда трудно найти, потому что подсказки, которые вы находите (например, сотни строк просочились), могут произойти не потому, что те объекты, которые непосредственно ответственны за строки, протекают, а потому, что что-то протекает этот объект. Часто вам приходится копаться в листьях и ветвях протекающего «дерева», чтобы найти «корень» проблемы.

Предотвращение: одно из моих главных правил - действительно, действительно, действительно избегать выделения объекта, просто не выпуская его автоматически прямо на месте. Везде, где вы размещаете / инициализируете объект, а затем освобождаете его позже в блоке кода, вы можете ошибиться. Либо вы забудете освободить его, либо создадите исключение, чтобы выпуск никогда не вызывался, либо вы поместили оператор return для досрочного выхода где-то в методе (чего я также стараюсь избегать).

0 голосов
/ 22 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...