2013-05-06 18 views
16

Tworzę aplikację, która jest rodzajem galerii - pokazuje różne treści multimedialne jako przeglądarkę pełnoekranową. Przydział instrumentu pokazuje, że parametr Live Bytes nie wzrasta powyżej 40 Mb podczas korzystania z aplikacji. Tymczasem aplikacja jest w 100% zabijana po tym, jak przesuwałam strony 20-30 razy. Sprawdziłem parametr Dirty Memory i stwierdziłem, że jest on 10 razy większy niż rozmiar Live Bytes. A najbardziej tego brudny pamięć spożywane Obrazek IO:Zabrudzona pamięć ImageIO nie jest automatycznie czyszczona przez iOS

Screenshot http://i40.tinypic.com/25ge51i.jpg

EDIT, kolejny zrzut ekranu:

Screenshot http://i40.tinypic.com/9t1mh5.png

Przydziały szczyty powyżej przełączanie treści multimedialne video/obraz. Problem polega na tym, że brudna pamięć rośnie prawie liniowo i muszę ją jakoś uwolnić.

Teraz o projekcie aplikacji. Ekran aplikacji ma jeden poziomy widok przewijania. Widok przewijania zawiera filmy lub obiekty kolażu zawierające wiele obrazów. Aby zaoszczędzić pamięć, tworzone są tylko trzy strony naraz - bieżąca strona i strony po lewej/prawej stronie. Więc strony zawsze tworzone i usuwane w locie podczas przesuwania widoku przewijania.

Wszystkie obrazy ładowane przy użyciu metody [UIImage imageWithContentOfFile: path]. Przechowywanie obiektów kolażu UIImage wystąpień wewnątrz imagesArray. W metodzie dealloc imageArray atrybut jest wyczyszczony.

Więc pytania:

  • Czy jest to rodzaj systemu bug w [UIImage imageWithContentOfFile?]
  • Czy Obraz IO cache?
  • Czy mogę to wyczyścić?
+0

To nie jest błąd w iOS - czy to tysiące aplikacji nie będzie działać. W jakiś sposób twoje obrazy nie są uwalniane. –

+0

Oczywiście problem w moim programie, ale jak widać na zrzucie ekranu, pamięć użytkownika jest wyczyszczona poprawnie (pierwszy wykres pokazuje ograniczone zużycie). Z drugiej strony widzimy ogromny, brudny przyrost pamięci. I naprawdę nie rozumiem, jaki to może być problem. Przy okazji, zapisałem metodę dealloc i zobaczyłem, że została wywołana. – ZAN

+1

Co zatem pokazuje trójkąt ujawnienia dla Image_IO? Oznacza to, że wystawisz listę i zaktualizujesz swoje pytanie. –

Odpowiedz

19

Wyrażając to tutaj jako zbyt duże dla komentarzu, zaledwie kilka pomysłów:

1) jednym ze sposobów na utrzymanie obiektów przez pomyłkę jest, aby obiekty w widoki, które się schować, ale nie usunięte z ich SuperView (i zatem pozostać zachowane)

2) jeśli robisz coś z UIImageView etc na każdym wątek nie główny wątek złe rzeczy mogą się zdarzyć (tak)

3) skopiować swój projekt, dzięki czemu można swobodnie bałagan z nim, i spróbuj wielu rzeczy:

  • zamiast wielu obrazów, zawsze ładuj ten sam obraz, ale pozostawiaj pozostałe części kodu w obecnej postaci - czy rzeczy się zmieniają?

  • W utworzonych podklasach, które przechowują/zatrzymują obrazy, umieść komunikat dziennika w dealloc, aby zobaczyć, czy w rzeczywistości obiekty te są deallocowane.

  • podklasa UIImageView, użyć go do obrazów i rejestrować dealloc

  • podklasy UIImage, używać go do tych obrazów, należy zalogować się dealloc

4) Mam trudny czas wiara imageio ma wadę, która by to zrobiła, ale możesz to zrobić, przełączając się na imageWithData i ładując dane samodzielnie. Użyj flagi F_NOCACHE, kiedy faktycznie czytasz dane - jest inny kod na SO, jak to zrobić, możesz go przeszukać (odpowiedziałem na to pytanie).

Jeśli można utworzyć projekt demonstracyjny z tą wadą, byłoby znacznie łatwiej go debugować, niż tylko odgadnąć, co należy zrobić. Logowanie się do klasy, która dostaje dealloc'd, ma długą historię, ponieważ natychmiast zobaczysz, co się nie wyda, a następnie lepiej skup się na problemie.

+1

Problem rozwiązany. Wystąpiły instancje instancji UII. Kiedyś tworzyłem je za pomocą [UIImage imageWithContentOfFile: path], a autorelease pula nie zwalnia ich na czas. Po przejściu do jawnego zachowania/zwolnienia problemu minął problem. Najtrudniejszy dla mnie instrument alokacji nie wykazał dodatkowego zużycia pamięci. O ile widzę, UIImage nie zawiera danych bitmapowych, a jedynie odniesienie do ImageIO, które znajdowało się w brudnej przestrzeni pamięci. Wielkie dzięki dla Davida, zapewnił mnie, że to tylko problem z utrzymaniem, więc w końcu znalazłem wyciekłe przypadki. – ZAN

+0

Obecnie mam ten sam problem. Jednak moja aplikacja nie jest galerią obrazów, ale prostym interfejsem UIWebView. Stwarza to ponad wzrost ** Brudna pamięć **, z czego większość wynika z danych narzędzia Image IO i Performance. Czy wiesz, gdzie powinienem zacząć kopać? –

+0

@NikhilJJoshi, więc wypuść wersję internetową i zastąp ją nową od czasu do czasu. To wszystko, co mogę wymyślić. Prawdopodobnie zbyt długo utrzymuje się na poprzednich stronach. Być może możesz ustawić zasady buforowania lub usunąć stare strony - nie masz dużego doświadczenia z tą klasą. –

0

Oprócz odpowiedzi David H za I polecam każdemu, kto doświadcza tego problemu również sprawdzić czy, UIDocument „s (jeśli używasz go) deinitializers nazywane są Państwa zdaniem kontrolera, modelu gdy nie są potrzebne.

Jeśli nie prawidłowo zwolnisz tych klas i zawierają one dane obrazu/VDO/treści, które odnosi się do tego UIKit, może to spowodować, że użycie pamięci zawsze będzie wzrastać, a mimo to widzisz nie ma wycieku pamięci podczas korzystania z Instruments, ponieważ te treści są teraz przechowywane wewnętrznie przez UIKit.

Doświadczyłem tego również dwa razy, aw moim przypadku okazało się, że deinicjant mojego modelu nigdy nie został wywołany z powodu niepowiązanych problemów. Rozwiązując te niezwiązane ze sobą problemy i upewniając się, że mój model jest dealokowany, ten ciągły wzrost zniknął.

enter image description here