Инструмент утечки памяти сообщает мне об отсутствии утечек, но объем памяти продолжает расти - PullRequest
2 голосов
/ 26 февраля 2010

Я выполняю некоторое профилирование памяти для своего приложения в SDK 3.2, и я использовал профилировщик 'Leak', чтобы найти все утечки памяти, и я подключил их все. Это приложение scrollView navigationController, в котором есть плитки, и вы щелкаете плитку, которая переходит к новому виду плиток и т. Д., Я могу пройти много уровней и пройти весь путь назад, а профилировщик «Утечка» говорит все это круто.

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

Я знаю, что это расплывчатое описание приложения, но я не могу точно опубликовать миллионы строк кода :) Также следует отметить, что я использую coreData для хранения данных изображений по мере продвижения, поэтому база данных растет размер, поскольку выбрано больше узлов, не знаю, если / когда это будет освобождено из памяти.

Что дает?

Ответы [ 6 ]

4 голосов
/ 10 марта 2010

Звучит так, как будто это может быть одна из нескольких вещей:

  • Память не возвращена ОС после освобождения. Это общий дизайн для C времени выполнения. Когда вы делаете выделение, среда выполнения C выделяет больше памяти для ее использования и возвращает ее часть для использования. Когда вы освобождаетесь, среда выполнения C просто помечает ее как освобожденную, но не возвращает ее обратно в ОС. Таким образом, если Leak Tool читает статистику уровня ОС, а не статистику времени выполнения C, Leak Tool не сможет сообщить о соответствующем снижении использования памяти.

  • Неверные значения, сообщаемые Leak Tool Memory. Leak Tool может искать значения, отличные от времени выполнения C, и сообщать о значениях, которые могут вызвать у вас беспокойство, даже если в этом нет ничего плохого (точно так же, как люди пытаются использовать диспетчер задач в Windows для обнаружения утечек и сильно путаются с результатами, потому что действительно очень плохой инструмент для этой работы).

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

Я думаю, что первое из этих трех предложений, скорее всего, происходит.

3 голосов
/ 26 февраля 2010

В зависимости от того, как ваш граф объектов построен в Базовых данных, его использование памяти может неожиданно возрасти.

Распространенной ошибкой является хранение объектов внутри сложного и часто неисправного (загруженного в память) объекта. Это приводит к тому, что большой BLOB-объект загружается / остается в памяти при обращении к какой-либо другой части объекта. По мере роста вашего графа объектов он потребляет все больше и больше памяти, если вы активно не удаляете объекты, а затем сохраняете график.

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

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

1 голос
/ 10 марта 2010

Информация об управлении памятью данных ядра является хорошей информацией, и технически ответ Артура Каллиокоски является хорошим ответом о разнице между распределением лука-порея и распределением объектов. Моя конкретная проблема здесь связана с явно известной ошибкой с setBackgroundImage на кнопке в симуляторе, она создает «утечку» памяти в том смысле, что не освобождает память для UIImage.

1 голос
/ 26 февраля 2010

Для повторения:

char *str1 = malloc(1000);
char *str2 = malloc(1000);
  .
  .
  .
char *str1000 = malloc(1000);

не утечка памяти, а

char *str1 = malloc(1000);
char *str1 = malloc(1000);  //Note! No free(str1) in between!

утечка памяти

1 голос
/ 26 февраля 2010

Тот факт, что нет утечек на основе refcount, не означает, что вы не помещаете что-то в «кеш» Словаря и не забываете об этом; они не будут отображаться как утечки, потому что на него есть действительные ссылки (условие остается в силе, как и ссылки на все его дочерние элементы). Вы также должны искать действительные, но ненужные ссылки на объекты.

Самый простой способ - просто позволить ему работать слишком долго, затем отсортировать количество объектов по типу и посмотреть, у кого есть гигантское число, - а затем отследить контрольный граф (может быть сложно в Obj-C?). Если Instruments не делает этого напрямую, вы можете написать для этого скрипт DTrace.

0 голосов
/ 26 февраля 2010

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

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