Память приложения для iPhone продолжает расти - PullRequest
4 голосов
/ 02 декабря 2011

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

Я протестировал несколько областей моего приложения, но я сосредоточился на паре больших областей, где продолжительное использование пользователем может очень легко вывести память из-под контроля. Мне трудно прочитать информацию из Allocations / Heapshots, так что я надеюсь, что кто-нибудь там сможет Rosetta Stone получить этот вывод для меня.

Я постараюсь дать как можно больше подробностей, а если этого недостаточно, просто орать, и я напишу больше.

Приложение запускается в меню. Нажатие на кнопку вызывает представление через presentModalViewController. Представление появляется, и в фоновом режиме открывается база данных, и выбирается и сохраняется случайная строка. Таким образом, цикл: Нажмите на Главное меню-> Открыть вид-> Закрыть вид, что заставляет мою память расти со скоростью 10–25 КБ каждый раз.

Некоторые мысли:

  • Некоторые части моего вида создаются через IB, с некоторыми кнопками быть пользовательских .png файлов. Я читал, что более ранняя сборка имела проблемы освобождение и перераспределение этих ресурсов, которые вызвали утечки памяти.
  • Я использовал button.layer.borderWidth / borderColor / cornerRadius / backgroundColor с некоторыми из моих кнопок, которые были изначально созданы в IB. Это нет-нет? (Удаление их немного помогает, но проблема все еще проявляется).

Для тех, кому интересно, это стек вызовов для самого большого роста кучи:

0 libSystem.B.dylib calloc
1 CoreGraphics CGGlyphBitmapCreate
2 CoreGraphics CGFontCreateGlyphBitmap8
3 CoreGraphics CGFontCreateGlyphBitmap
4 CoreGraphics CGGlyphLockLockGlyphBitmaps
5 libRIP.A.dylib ripc_DrawGlyphs
6 CoreGraphics draw_glyphs
7 CoreGraphics CGContextShowGlyphsWithAdvances
8 WebCore WebCore::showGlyphsWithAdvances(WebCore::FloatPoint const&, WebCore::SimpleFontData const*, CGContext*, unsigned short const*, CGSize const*, unsigned long)
9 WebCore WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const
10 WebCore WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
11 WebCore WebCore::Font::drawText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const
12 WebKit drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, bool, WebCore::BidiStatus*, int)
13 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:drawUnderline:]
14 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:]
15 WebKit -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:]
16 WebKit -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:]
17 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:]
18 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:baselineAdjustment:includeEmoji:]
19 UIKit -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:baselineAdjustment:]
20 UIKit -[UILabel _drawTextInRect:baselineCalculationOnly:]
21 UIKit -[UILabel drawTextInRect:]
22 UIKit -[UILabel drawRect:]
23 UIKit -[UIView(CALayerDelegate) drawLayer:inContext:]
24 QuartzCore -[CALayer drawInContext:]
25 QuartzCore backing_callback(CGContext*, void*)
26 QuartzCore CABackingStoreUpdate_
27 QuartzCore CA::Layer::display_()
28 QuartzCore -[CALayer _display]
29 QuartzCore CA::Layer::display()
30 QuartzCore -[CALayer display]
31 QuartzCore CA::Layer::display_if_needed(CA::Transaction*)
32 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
33 QuartzCore CA::Transaction::commit()
34 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
35 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
36 CoreFoundation __CFRunLoopDoObservers
37 CoreFoundation __CFRunLoopRun
38 CoreFoundation CFRunLoopRunSpecific
39 CoreFoundation CFRunLoopRunInMode
40 GraphicsServices GSEventRunModal
41 GraphicsServices GSEventRun
42 UIKit UIApplicationMain
43 GRE Words main /Users/admin/Dropbox/GRE Words/main.m:14
44 GRE Words start

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

Спасибо.

1 Ответ

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

Используйте Heapshot, чтобы найти разрыв в памяти, см .: bbum blog

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

Чтобы выяснить результаты, откройте для просмотра отдельные распределения.

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

Запустите инструменты, в Allocations включите «Record reference counts» on (вы должны остановить запись, чтобы установить опцию).Заставьте сборщик запустить, остановить запись, найти там ivar (datePickerView), выполнить детализацию, и вы сможете увидеть, где произошли все сохранения, выпуски и автоматические выпуски.

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

...