2013-09-03 9 views
21

Używam mojego iOS na urządzeniu iPod touch i dostaję ostrzeżenia pamięci nawet jeśli całkowita szczyt alokacja jest tylko 7 MB jak pokazano poniżej (to się dzieje, gdy Scena Gra jest wciśnięty):Dlaczego otrzymuję ostrzeżenia o pamięci z przydzielonymi tylko 7 MB pamięci?

low memory warning

Co znajdę dziwne jest to, że:

  • lewej szczyt (w czasie 0.00) odpowiada 20 MB pamięci przydzielonej (Scena wprowadzająca) i pomimo tego NIE daje żadnego ostrzeżenia o pamięci.

  • Centralny szczyt (w czasie 35,00) centralnego wierzchołka odpowiada 7 000 MB pamięci przydzielonej (Scena gry jest pchana) i wyświetla ostrzeżenie o pamięci.

Nie rozumiem, dlaczego dostaję te ostrzeżenia, jeśli całkowita pamięć to tylko 7 MB. Czy to normalne? Jak mogę tego uniknąć?

Density peaks

Patrząc na gęstość rozdziału widzimy następujący schemat, który (dla mnie) nie wykazuje dużej różnicy pomiędzy momentem, kiedy Intro Scena jest popychany (0,00), a moment, w którym Scena gry jest pchana (35,00). Będąc szczytem gęstości podobnym, zakładam, że ostrzeżenia o pamięci są spowodowane czymś innym, że nie jestem w stanie wykryć.

EDIT:

śledzę sugestię używać „Monitor aktywności” zamiast ale niestety moja aplikacja wywala podczas ładowania sceny gra z tylko 30 MB pamięci przydzielone. Oto raport monitorowania aktywności.

Activity monitor report

Patrząc na raport widzę całkowitą sumę rzeczywistego wykorzystania pamięci około 105 MB. Biorąc pod uwagę to powinno odnosić się do pamięci RAM i biorąc pod uwagę mój model powinien mieć 256 MB pamięci RAM, nie powinno to spowodować awarie APP lub problemy z wyciekiem pamięci.

Uruchamiam monitor wycieku i nie wykazuje on żadnych nieszczelności w mojej aplikacji. Zabiłem też wszystkie inne aplikacje.

Jednak analizując raport, widzę zdumiewającą 167 MB wartości pamięci wirtualnej powiązanej z moją aplikacją. Czy to normalne? Co oznacza ta wartość? Czy to może być przyczyną katastrofy? Jak mogę wykryć, które obszary mojego kodu są za to odpowiedzialne?

Virtual memory

My iPod 4th Generation modelu z 6,4 GB pojemności (pamięć), a tylko 290 MB wolnej pamięci. Nie jestem pewien, czy to w jakiś sposób wpływa na wydajność pamięci wirtualnej paging.

EDIT 2: Spojrzałem również na SpringBoard, a jego wykorzystanie pamięci wirtualnej wynosi 180 MB. Czy to normalne?Znalazłem trochę questions/answers, które wydaje się sugerować, że SpringBoard jest odpowiedzialny za autoodtwarzanie obiektów (powinien to być proces zarządzania ekranem i bottonem w domu, ale nie jestem pewien, czy ma to również związek z zarządzaniem pamięcią). Czy to jest poprawne?

Kolejna uwaga. Używam ARC. Jednak nie jestem pewien, że to ma wiele wspólnego z problemem, ponieważ nie ma widocznych wycieków pamięci, a XCode powinien przekonwertować kod dodając wywołania release/dealloc/keep do skompilowanego pliku binarnego.

EDYCJA 3: Jak powiedziałem wcześniej używam ARC i Cocos2d (2.0). Bawiłem się z monitorem aktywności. Dowiedziałem się, że jeśli usunę mechanizm uwierzytelniania GameCenter, wtedy Monitor aktywności działa dobrze (nowa wątpliwość: czy ktoś inny miał podobny problem? Czy widok uwierzytelniania GameCenter jest gdzieś przechowywany?). Zauważyłem jednak, że za każdym razem poruszam się w tył i w przód pomiędzy różnymi scenami przed GameScene (Początkowa scena -> Wybór postaci -> Wybór planety -> Wybór postaci -> Wybór planety -> itd. -> Wybór postaci ..) Zużycie PRAWDZIWEGO użycia wzrasta o. Po pewnym czasie zacznę otrzymywać ostrzeżenia z pamięci i aplikacja zostanie zabita przez iOS. Teraz pytanie brzmi:

-> Czy zastępuję sceny w prawidłowy sposób? Wzywam następujące z różnych scen:

[[CCDirector sharedDirector] replaceScene: [MainMenuScene scene]]; 

mam Cocos2d 2.0 jako statyczna biblioteka i kod replaceScene to:

-(void) replaceScene: (CCScene*) scene 
{ 
    NSAssert(scene != nil, @"Argument must be non-nil"); 

    NSUInteger index = [scenesStack_ count]; 

    sendCleanupToScene_ = YES; 
    [scenesStack_ replaceObjectAtIndex:index-1 withObject:scene]; 
    nextScene_ = scene; // nextScene_ is a weak ref 
} 

Zastanawiam się, czy jakoś scena nie dostać dealokowane prawidłowo. Zweryfikowałem, że wywoływana jest metoda czyszczenia, ale dodałem również wywołanie CCLOG w metodzie dealloc CCLayer i przebuduję bibliotekę statyczną. W rezultacie metoda dealloc nie wydaje się być nazwana.

Czy to normalne? : D

Znalazłem, że inni ludzie mieli similar issues. Zastanawiam się, czy ma do czynienia z retain cycles and self blocks. naprawdę trzeba poświęcić trochę czasu na studiowanie tego, chyba, ze EDIT 3, może ktoś mi powiedzieć już, co robię źle :-)

+1

Wszelkie inne aplikacje uruchomione w tle? –

+5

Pamięć graficzna, np. w przypadku dużych obrazów lub tekstur nie pojawi się w przydziale Allocations. Zamiast tego użyj Monitora aktywności. –

+0

spróbuj nacisnąć i wrócić, aby zobaczyć ponownie kilka razy. Sprawdź, kiedy próbujesz nacisnąć i pop view, czy właśnie otrzymujesz ostrzeżenia o pamięci? – Manthan

Odpowiedz

0

Rozwiązałem to przez dodanie druk efektywnej pamięci procesu użycie w konsoli. W ten sposób mogłem uzyskać dokładną analizę rzeczywistej pamięci używanej przez proces App.Używanie instrumentu okazało się nieprecyzyjne, ponieważ prawdziwa pamięć nie pasowała do tego, które pokazano na instrumentach.

Ten kod może być użyty, aby uzyskać efektywne wykorzystanie pamięci:

-(vm_size_t)report_memory 
{  
    struct task_basic_info info; 
    mach_msg_type_number_t size = sizeof(info); 
    kern_return_t kerr = task_info(mach_task_self(), 
            TASK_BASIC_INFO, 
            (task_info_t)&info, 
            &size); 
    if(kerr == KERN_SUCCESS) { 
    } else { 
     NSLog(@"Error with task_info(): %s", mach_error_string(kerr)); 
    } 
    return info.resident_size; 
} 
+1

Cóż, jeśli masz dodatkowe informacje/pomoc na ten temat, mam do czynienia z dokładnie ten sam problem :( –

+0

@Zil przepraszam nie otrzymałem powiadomienia o komentarzu .. Spoglądam na mój kod źródłowy (nie jest na moim komputer teraz) i pobrać kod, którego użyłem do jego wydrukowania – mm24

+6

A odpowiedź była ...? – Chris

3

wszystkich pojemności pamięci współdzielonej przez wszystkie aplikacje & procesy działają w systemie iOS. Inne aplikacje mogą więc korzystać z dużej ilości pamięci, a Twoja aplikacja również otrzymuje ostrzeżenie o pamięci. Otrzymasz ostrzeżenia o pamięci, dopóki to nie wystarczy.

Aby zrozumieć, co się właściwie dzieje z pamięcią w aplikacji należy

  1. profilu aplikację z Przecieki (ARC nie ma gwarancji, że nie ma wycieków, czyli samodzielne uchwycenie problemu).

  2. analiza Wykorzystanie heapshot (krótko opisane tutaj http://bentrengrove.com/blog/2013/4/26/heapshot-analysis)

A kasa to post o pamięć & pamięci wirtualnej w systemie iOS: http://liam.flookes.com/wp/2012/05/03/finding-ios-memory/

+0

Dzięki za odpowiedź. To zdecydowanie pomaga mi myśleć o ARC i problemach z przechwytywaniem. Prowadzę dochodzenie w tej sprawie i dodałem trochę wglądu do mojego problemu w pytaniu (zobacz EDYCJA 3). Nadal nie rozwiązany, więc jakakolwiek dalsza pomoc ze strony kogokolwiek byłaby bardzo poważana. – mm24

Powiązane problemy