Как я могу отследить пики памяти? (Это пики с р, а не л.) - PullRequest
10 голосов
/ 01 августа 2011

У меня есть приложение для киоска, которое, по сути, показывает кучу слайдов с различной информацией.Сначала я начал писать код более года назад, когда начинал разработку Objective-C и iOS.Я обнаружил, что мой стиль кода теперь намного чище, чем был, и я гораздо опытнее, поэтому я решил переписать его с нуля.

Я запустил свое приложение с инструментом Allocations, чтобы посмотреть, как использовалась память.Учитывая, что это приложение для киосков, все должно работать без сбоев.(Конечно, все приложения должны работать без утечек, но приложение киоска делает это еще более важной целью.) Я увидел некоторые интересные результаты, поэтому я также запустил старую версию кода.

Запускболее старая версия кода, я вижу, даже работает на 1,15 мегабайта памяти.Кажется, все распределяется и освобождается по мере необходимости.Однако в моей новой реализации я вижу что-то немного другое.Использование памяти постоянно растет в небольших «плато», а затем, в конечном итоге, достигает пика в 1,47 мегабайта.Вот как выглядит новый отчет Allocations после более 10 часов работы:

enter image description here

Я обеспокоен по нескольким причинам.

  1. Нечетный шаблон в начале цикла.
  2. Распределение кажется, что достигает пика в 1,47 мегабайта, но его запуск в одночасье показывает, что он на самом деле будет медленновсе больше и больше памяти со временем.Это не может быть хорошей вещью.

Есть несколько заметных различий между старым проектом и новым.

  • Более старый использует Plists в качестве резервного хранилища (я вручную читаю и записываю в файл plist.) Новый проект использует Core Data.

  • В новом проекте реализована библиотека, которая вызывается на каждом «слайде», которого у старого проекта не было.Я был бы более обеспокоен этой библиотекой, за исключением того, что я написал ее, и я прошел ее, чтобы убедиться, что я выпускаю все и только автоматически выпущен, где ручные выпуски были невозможны.

  • Оба класса используютфабричный класс для создания слайдов.В старом проекте заводской класс был синглтон.Я думал, что превращение этого в нормальный класс поможет с проблемами памяти, так как синглтон никогда не выпускался.(Следовательно, это свойства не были выпущены. В новом проекте выпускается фабричный класс, поэтому я не уверен, почему он все еще занимает всю эту память (если это и является причиной проблемы.

  • В старом проекте используются строковые константы в разных местах. В новом коде для одной и той же вещи используется массивное перечисление. (В целом новый код использует больше констант.)

Что я могу сделать, чтобы отследить пики памяти? Память очищается приложением, когда оно отбрасывает все, что использует, но, похоже, не отбрасывает вещидо тех пор, пока приложение не закроется.

Буду признателен, если кто-нибудь поможет мне указать правильное направление.

Редактировать:

Это выглядит как будто пик вызван вызовами библиотеки KosherCocoa . Если кто-то возражает взглянуть на это и сказать, что я делаю там неправильно,насколько управление памятью идет, я быдействительно ценю это.

1 Ответ

5 голосов
/ 01 августа 2011

Что я могу сделать, чтобы отследить пики памяти? Память все время очищено приложением, когда оно отбрасывает все, что оно использует, но это, кажется, не отбрасывает вещи.

Это классический случай "брошенных объектов" или "увеличения использования". То есть, у вас есть приложение, которое при запуске создает граф объектов в памяти как обычную часть использования. Объекты не просочились, потому что они все еще связаны с графом живых объектов. Скорее всего, объекты являются частью какого-либо кеша (чаще всего кеша только для записи) или механизма, связанного с историческим состоянием (стек отмены является потенциальным источником накопления).

Чтобы исправить это, вы должны убедиться, что ваш граф объектов корректно сокращен во время работы вашего приложения. Кэши обычно должны использовать алгоритм сокращения [LRU], который используется не так давно, который ограничивает размер кэша. Если ключ кеша становится недействительным, эти данные тоже должны быть удалены.

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

Используйте анализ Heapshot - он был создан, чтобы помочь отследить именно такие проблемы.

Я написал подробное руководство "Как сделать"; Когда утечка не утечка?

...