Программа получила сигнал: «0». Никаких предварительных признаков проблем - PullRequest
2 голосов
/ 15 декабря 2011

Запуск долго работающего приложения для обработки звука на привязанном (к Xcode 3) iPod Touch. Дважды сейчас, после 1 часа 40 минут в первый раз и 2 часов 20 минут во втором, приложение заканчивало с сигналом 0. Здесь и на других форумах многократно обсуждается сигнал 0, и все они, кажется, виноваты в нехватке памяти .

Но я сбрасываю память, используемую через определенные промежутки времени, и в последнем тесте она увеличилась всего на 3,3 Мб с начала цикла и до конца. И у меня есть крючок в моем делегате приложения, чтобы войти, если я получаю предупреждение памяти (проверил это на симуляторе), и это не вызывалось.

Короче говоря, нет предположения о нехватке памяти.

В обоих случаях приложение было закрыто в той точке программы, где файлы записываются и передаются на сервер. (Это происходит каждые 20 минут.) Передаваемые файлы являются относительно небольшими (86 КБ для переданного в момент сбоя). Судя по журналам, возможно, произошла ошибка при чтении файла для подготовки к передаче. Это потребовало бы создания строки NSString, содержащей данные для передачи. (Возможно, логика здесь может быть немного чище - она ​​использует NSString stringByAppendingFormat, что, я признаю, подозрительно.)

Есть предложения, как это отладить? Это звонит в колокол? Могу ли я выйти из хранилища без предупреждения? Есть ли что-то, что может "заснуть" на телефоне? Есть ли какой-то предел того, как долго вы можете запустить привязанный тест на Xcode 3?

Ответы [ 2 ]

0 голосов
/ 17 декабря 2011

Я не уверен, что это окончательный ответ, но я «массировал» код за последние пару дней и исправил несколько проблем, связанных с хранилищем. Было исправлено несколько небольших утечек («Утечки» - неоценимое занятие, но интерфейс вроде sux), но, что более важно, я исправил одно место в коде (на которое я ссылался в моем первоначальном посте), которое, вероятно, выделяло около 100 МБ в одном метод. Все хранилище было автоматически освобождено, но это все еще означало, что оно создало существенную преграду в кривой распределения. (И то, где все это произошло, очень близко соответствовало тому, где произошла авария.)

После этих исправлений приложение работало более 3 часов - не совсем готов объявить о победе, но выглядит хорошо.

(Уродливый код (не мой!) Неоднократно использовал stringByAppendingFormat для создания относительно длинной строки для передачи по сети. Если у вас есть N строк длины M для объединения вместе, и вы постоянно используете stringByAppendingFormat для выполнения это, результат примерно N * M, но вы строите около N * N * M / 2 хранилища, чтобы построить его. Если N порядка 2000, это становится большим числом. И хотя все это автоматически выпущено, оно все еще накапливается до тех пор, пока не истощится пул. Использование функций добавления NSMutableString намного эффективнее.)

0 голосов
/ 15 декабря 2011

Я могу только предложить вам обернуть NSAutoreleasePools весь ваш код, который использует автоматически выпущенные объекты, созданные в циклах. Каждый созданный вами автоматически выпущенный объект добавляется в основной пул автоматического выпуска, поэтому общее распределение памяти увеличивается и увеличивается до тех пор, пока система не выдаст предупреждение о памяти и не закроет ваше приложение.

Подробнее об NSAutoreleasepool:

http://www.cocoadev.com/index.pl?NSAutoreleasePool

Или вот из документов:

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

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

...