Утечки памяти, вызванные из-за CoreFoundation Framework - PullRequest
5 голосов
/ 10 января 2011

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

Для целей нагрузочного тестирования я добавил в приложение 10 000 тегов.Но во время нагрузочного тестирования моего приложения я обнаружил некоторые утечки памяти, которые не были связаны с кодом приложения, но представляют собой набор наборов инструкций.Кроме того, Инструменты показали Фонд как ответственную библиотеку за Утечку (Широкое использование NSString, NSDictionary, NSArray, которое принадлежит структуре Фонда).Мое приложение аварийно завершает работу после 10–15 минут использования. В отчете о сбое упоминается сбой приложения из-за нехватки памяти.

Профилирование памяти с использованием CLANG показывает отсутствие утечек.Как мне решить эти утечки памяти?Являются ли эти утечки настоящим виновником аварии?Есть ли другие инструменты для проверки утечек памяти?

Ответы [ 4 ]

4 голосов
/ 18 января 2011

Я часто нахожу, что мои утечки говорят, что они вызваны Core Foundation (или любой другой платформой в этом отношении), но на самом деле мои собственные За исключением симулятора, вы редко найдете чрезмерную утечку в фреймворках.

Если вы откроете панель сведений справа в разделе «Инструменты», вы можете найти там перечисленные методы вашего приложения. Это даст вам представление о том, откуда оно может появиться в вашем коде. Одна утечка может привести к множеству других утечек, и вам, возможно, придется найти виновника верхнего уровня, чтобы избавиться от нижестоящих.

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

1 голос
/ 23 января 2011

Скорее всего, у вас есть код, который создает объекты фундамента. Утечки показывают вам место выделения, но это обычно происходит из-за вызова, который ваш код сделал для создания объекта. Вы можете посмотреть цепочку вызовов в Instruments и вернуться назад по цепочке вызовов, пока не дойдете до своего кода - это место, где вы вызываете распределение. Теперь, для этого распределения, посмотрите на вашу обработку памяти для этого объекта: вы освобождаете его через некоторое время?

Есть много способов, которыми вы не можете освободить свойство памяти, поэтому было бы трудно догадаться, какой из них вы можете ударить. Я вижу, когда помогаю людям распределить объект и назначить его переменной экземпляра через свойство с атрибутом retain, что-то вроде этого:

@ свойство (сохранить) NSString * myString;

...

self.myString = [[NSString alloc] initWithString: @ "foo"];

alloc + init создает сохраняемый объект, self.myString = снова увеличивает счетчик сохраняемых данных. При правильном кодировании метод dealloc освобождает свойство через одно из:

[выпуск myString]; или же self.myString = ноль;

И это заботится о сохранении, добавленном с self.myString =, но НЕ заботится о сохранении от создания. Решения, ОДИН из следующих:

myString = [[NSString alloc] initWithString: @ "foo"]; // не вызывает метод setter, поэтому присваивание не сохраняется, но не вызывает setter, что может быть плохо, если нетривиальный setter.

self.myString = [[[NSString alloc] initWithString: @ "foo"] autorelease];

автоматическое освобождение освобождает alloc + init.

Теперь, конечно, это надуманный пример, потому что вы, вероятно, действительно использовали бы:

self.myString = [NSString stringWithString: @ "foo"];

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

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

1 голос
/ 18 января 2011

лязг не проверяет утечку. Он обнаруживает только небольшое подмножество проблем.

Для отладки утечек памяти вы должны сосредоточиться на инструментах, в частности на инструментах «Распределение объектов» и «Утечки». Обязательно поймите разницу между утечками и другими источниками высокого использования памяти.

Как только вы определили, что объекты имеют утечку, используйте Инструменты, чтобы проверить их трассировку стека выделения (чтобы вы могли определить, что это за объект) и историю их сохранения / выпуска.

Если это не утечка, тогда я предлагаю изучить инструкции здесь: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

0 голосов
/ 18 января 2011

Попробуйте решить некоторые проблемы в коде: 1. Пожалуйста, избегайте скрывать декларации, такие как

NSString *string = [dictionary valueForKey:[dictionary2 valueForKey:@"something"]]

Правильный код:

NSString *key = [dictionary2 valueForKey:@"something"];  
NSString *string = [dictionary valueForKey:key];
key = nil;
  1. Старайтесь избегать объявления с автоматическим выпуском и локальной декларацией, например:

    NSArray * array = [NSArray array];

Если вы делаете это, убедитесь, что у вас есть:

NSArray *array = [NSArray array];
.... some code where array is using;
array = nil;

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

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

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