Не удается найти источник утечки памяти - PullRequest
1 голос
/ 29 июля 2010

Я пишу приложение (в основном это еще один клон iBooks), которое потребляет много памяти.В зависимости от входных данных его объем памяти может достигать 70-80 МБ (как утверждает MemoryMonitor) или даже больше.
В течение некоторого времени он работает нормально, но со временем имеет тенденцию увеличивать объем памяти.
Допустим, вы открываете книгу, и объем памяти приложения увеличивается с 6 до 60 МБ.Затем должно произойти то, что вы закрываете книгу, и объем памяти уменьшается до 6 МБ.И это не так.Он уменьшается до ~ 30 МБ (согласно MemoryMonitor), что приводит к падению всего за несколько итераций.

Теперь интересная часть.Я пробовал статический анализатор clang, но он не показывает проблем (кроме указания на синглтоны и т. Д.).
Я пробовал использовать инструменты с утечками, но они показывают, что у меня всего 2-3 КБ (и это должно быть ~24MB +).Более того, я не обеспокоен тем, что инструменты на самом деле говорят мне правду.Я дважды проверил все утечки, о которых сообщают инструменты, и я на 99% уверен, что там нет утечек.
Я попытался использовать инструмент распределения, но он показывает, что после закрытия книги объем памяти сокращается до6 МБ, что является желаемым числом.Но это не имеет особого смысла, так как если бы это было так, приложение никогда бы не рухнуло.Я также попытался использовать профилировщик openglES для графика байтов ресурса, но он также не показывает утечек или чего-либо еще подозрительного.
Единственным инструментом, которому я доверял, был монитор памяти, потому что мое приложение всегда вылетало при отображении~ 110 МБ используемой реальной памяти.Тем не менее, а) он не показывает, что выделяет память, и б) когда я попытался запустить его несколько раз с одной и той же сборкой приложения, я обнаружил, что его показания резко отличаются от запуска к запуску (разница 15-20 МБ при выполнении именното же самое).

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

Так что это мои вопросы:
1) Есть ли способнайти утечки помимо упомянутых выше?Может быть, другая программа-профилировщик для iphone?
2) Я читал о каких-то проблемах дефрагментации, например, когда вы выделяете / перераспределяете много объектов, а затем приложение не возвращает освобожденные блоки обратно в ОС, что может сделать это невозможнымвыделять большой блок памяти только потому, что он слишком фрагментирован и ОС не дает вам больше памяти.Я никогда не видел хорошую тему об этом до конца.Если бы кто-то мог сэкономить ссылку на связанную тему, это было бы здорово.
3) Я попытался отключить несколько частей программы, и до сих пор похоже, что вся проблема может быть связана с использованием инфраструктуры CoreText.Я хотел бы услышать от любого, кто когда-либо интенсивно использовал эту платформу и может подтвердить / опровергнуть, что там есть какие-либо проблемы.
4) - любые другие предложения -

PS Я не включил ни однойфрагменты кода, потому что сам код довольно большой, и я не могу уменьшить количество подозрительного кода до разумного.

Ответы [ 2 ]

2 голосов
/ 30 июля 2010

Возможно, немного глупо, но когда со мной произошло что-то похожее, я понял, что у меня включены NSZombies.С тех пор мой didFinishLaunching: имеет следующую пару строк вверху:

if (getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled")) {
    NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
} else {
    NSLog(@"No NSZombieEnabled or NSAutoreleaseFreedObjectCheckEnabled");
}
0 голосов
/ 29 июля 2010

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

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

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

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

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