Jak mogę pozbyć się brudnej pamięci rezydenta w Objective-C?

Oglądałem film WWDC 2010 firmy Apple na temat zaawansowanej analizy pamięci za pomocą instrumentów i dzięki temu udało mi się znaleźć dużo brudnej pamięci rezydenta. Zdaję sobie sprawę, że posiadanie tak dużej ilości brudnej pamięci to zła rzecz (i prawdopodobnie wyjaśnienie, dlaczego moja aplikacja tak bardzo się zawiesza...), ale nie wiem, jak to naprawić. Gdzie mam szukać?

Instrumenty pokazują mi wiele potencjalnie przydatnych informacji, które dla mnie wyglądają jak bełkot, takich jak:

% of Res  Type                      Resident Size
18%       VM_ALLOCATE (8192 pages)  32.00 MB

To jest w " Dirty" Kategoria-32 MB brudnej pamięci rezydenta to dużo na urządzeniu, które ma tylko 256 MB, prawda? :) Jest jeszcze kilka takich dużych kawałków. Jak wyśledzić to z powrotem do mojego kodu z instrumentów? A może powinienem po prostu zapomnieć o instrumentach i szukać konkretnych problemów w moim kodzie?

Author: Josh Brown, 2011-03-25

4 answers

Czy widzisz ten 32 MB fragmentu VM_ALLOCATE podczas pracy na urządzeniu lub w symulatorze?

Pytam, ponieważ kiedy bawiłem się instrumentem alokacji w aplikacji OS X, nad którą pracuję, zauważyłem również kawałek 32 MB VM_ALLOCATE i zastanawiam się, czy jest to produkt uboczny działania w środowisku OS X. Uruchomienie na urządzeniu może dać inny zestaw danych.

Ogólnie rzecz biorąc, pamięć rezydentna to pamięć używana przez aplikację, która nie jest zamieniana na dysk. W systemie iOS nie ma swapu, więc pamięć rezydentna powinna być równa Twojej pamięci wirtualnej.

Brudna pamięć to pamięć, którą przydzieliłeś i użyłeś. Brudna pamięć powinna być mniejsza niż pamięć rezydentna, ponieważ ta ostatnia zawiera kod (twój i frameworki).

Nie jestem pewien, co dokładnie robisz w swojej aplikacji, ale domyślam się, że załadowałeś kilka dużych zasobów ze swojego pakietu i trzymasz je w pobliżu. Nie rób tego, jeśli to możliwe.

Istnieją również API, których możesz użyć podczas ładowania obiektów NSData, które używają techniki mapowania pamięci zamiast brute-force odczytu bajtów. Te mogą być lepsze, ponieważ pozwala systemowi operacyjnemu leniwie czytać strony z dysku. Z NSData (ponieważ nie jest zmienny), może być również wystarczająco inteligentny, aby oznaczyć strony jako Tylko do odczytu. Teoretycznie jest to cenna wskazówka dla systemu operacyjnego, że może wyczyścić te strony, gdy jest pod presją, ponieważ wie, że nie mogą się zmienić. Przeczytaj dokumenty dla +[NSData dataWithContentsOfMappedFile:].

Dla obrazów, przypominam sobie, że czytam coś sugerowało to unikanie imageNamed: z wyjątkiem obrazów, które regularnie używasz za pośrednictwem aplikacji (np. elementów interfejsu użytkownika). Szczególnie w przypadku dużych obrazów mogą one pozostać w pamięci podręcznej, nad którą nie masz kontroli. (imageNamed: miał przeciek w 2.X dni, ale została ustalona w 3.x i jest całkowicie bezpieczny w użyciu dzisiaj.) Użyj imageWithContentsOfFile: dla większych obrazów i obrazów, które nie są powtarzającą się częścią interfejsu użytkownika.

Jeśli ładujesz obrazy z sieci, buforuj je na dysku i uwolnij surowe bajty po utworzeniu UIImage. Jeśli widoki obrazów są rozładowane z powodu presji pamięci, nie chcesz ponownie wczytywać danych w sieć, ale nie chcesz również przechowywać dwóch kopii (NSData i UIImage) wczytywanych.

 28
Author: Steve Madsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-03 18:52:42

Z nowym Xcode 4 narzędzia pochodzące z xCode 3 nadal tam z lepszym interfejsem użytkownika do profilowania aplikacji, w tym wycieków i wykorzystania pamięci. Polecam spojrzeć na te narzędzia i uruchomić jeden po drugim, aby zobaczyć, co zapewniają. Możesz uzyskać dostęp do tych narzędzi w xCode 4 w menu głównym produktu, a następnie - > Profil

Hope this helps

 2
Author: Al Pascual,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-25 22:22:29

W instrumentach kliknij Włącz migawki automatycznie Zmień tryb widoku na mapę regionów. Znajdź w ścieżkach nazwy plików, których u r używa podczas gdy u aplikacja mieszka w plikach vmpages I po tym, jak to wyczyścisz. W przykładzie wideo wwdc używali szyfrowania dla pliku i to było push go do vmpages, bez kodu u zbyt trudno zasugerować coś więcej niż [biblioteka flush]: -)

 1
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-01 11:09:26

"to jest w kategorii "brudne" - 32 MB brudnej pamięci rezydenta..." "Zauważyłem też 32 MB fragmentu VM_ALLOCATE i zastanawiam się..."

Widzę ten sam "vm_allocate (8192 stron) 32 MB" dla kolumn rezydentnych, brudnych i wirtualnych w vm Tracker, kiedy profiluję moje aplikacje w symulatorze.

Dla porównania, mam profilowane (mniejsze) aplikacje demo zbudowane z Paula Hegarty bardzo pouczające iTunes U Stanford course -- np psycholog i Kalkulator graficzny -- i zobacz ten sam wpis w każdym.

Jestem "facetem od domen" i nie mam jeszcze mocnego zrozumienia szczegółów zarządzania pamięcią, więc nie mogę zaoferować autorytatywnego wyjaśnienia, ale wydaje się rozsądne wnioskować, że ta alokacja jest należna elementom frameworka wspólnym dla wszystkich aplikacji uruchamianych na symulatorze. (Nie uruchamiałem ich na urządzeniu.)

Xcode 4.3 na MacBooku Pro z systemem 10.7.3)
 0
Author: Nick Staresinic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-06 13:27:15