2013-03-19 11 views
5

C'è una parte della mia app in cui eseguo operazioni contemporaneamente. Consistono nell'inizializzazione di molti CALayer e nel renderli in bitmap.VM Tracker mostra grandi dimensioni sporche

Sfortunatamente, durante queste operazioni (ognuna richiede circa 2 secondi per essere completata su un iPhone 4), la Dimensione sporca indicata da VM Tracker raggiunge i ~ 120 MB. Le allocazioni raggiungono il picco di ~ 12 MB (non si accumula) A mio parere, la dimensione sporca è memoria che non può essere liberata. così spesso la mia app e tutte le altre app in background vengono uccise.

Incident Identifier: 7E6CBE04-D965-470D-A532-ADBA007F3433 
CrashReporter Key: bf1c73769925cbff86345a576ae1e576728e5a11 
Hardware Model:  iPhone3,1 
OS Version:   iPhone OS 5.1.1 (9B206) 
Kernel Version:  Darwin Kernel Version 11.0.0: Sun Apr 8 21:51:26 PDT 2012; root:xnu- 

1878.11.10~1/RELEASE_ARM_S5L8930X 
Date:    2013-03-18 19:44:51 +0800 
Time since snapshot: 38 ms 

Free pages:  1209 
Active pages:  3216 
Inactive pages: 1766 
Throttled pages: 106500 
Purgeable pages: 0 
Wired pages:  16245 
Largest process: Deja Dev 

Processes 
     Name     UUID     Count resident pages 
      geod <976e1080853233b1856b13cbd81fdcc3>  338 
     LinkedIn <24325ddfeed33d4fb643030edcb12548> 6666 (jettisoned) 
    Music~iphone <a3a7a86202c93a6ebc65b8e149324218>  935 
     WhatsApp <a24567991f613aaebf6837379bbf3904> 2509 
     MobileMail <eed7992f4c1d3050a7fb5d04f1534030>  945 
     Console <9925a5bd367a7697038ca5a581d6ebdf>  926 (jettisoned) 
     Test Dev <c9b1db19bcf63a71a048031ed3e9a3f8> 81683 (active) 
    MobilePhone <8f3f3e982d9235acbff1e33881b0eb13>  867 
    debugserver <2408bf4540f63c55b656243d522df7b2>  92 
     networkd <80ba40030462385085b5b7e47601d48d>  158 
     notifyd <f6a9aa19d33c3962aad3a77571017958>  234 
     aosnotifyd <8cf4ef51f0c635dc920be1d4ad81b322>  438 
     BTServer <31e82dfa7ccd364fb8fcc650f6194790>  275 
CommCenterClassi <041d4491826e3c6b911943eddf6aaac9>  722 
    SpringBoard <c74dc89dec1c3392b3f7ac891869644a> 5062 (active) 
     aggregated <a12fa71e6997362c83e0c23d8b4eb5b7>  383 
      apsd <e7a29f2034083510b5439c0fb5de7ef1>  530 
     configd <ee72b01d85c33a24b3548fa40fbe519c>  465 
    dataaccessd <473ff40f3bfd3f71b5e3b4335b2011ee>  871 
    fairplayd.N90 <ba38f6bb2c993377a221350ad32a419b>  169 
     fseventsd <914b28fa8f8a362fabcc47294380c81c>  331 
      iapd <0a747292a113307abb17216274976be5>  323 
     imagent <9c3a4f75d1303349a53fc6555ea25cd7>  536 
     locationd <cf31b0cddd2d3791a2bfcd6033c99045> 1197 
    mDNSResponder <86ccd4633a6c3c7caf44f51ce4aca96d>  201 
    mediaremoted <327f00bfc10b3820b4a74b9666b0c758>  257 
    mediaserverd <f03b746f09293fd39a6079c135e7ed00> 1351 
     lockdownd <b06de06b9f6939d3afc607b968841ab9>  279 
      powerd <133b7397f5603cf8bef209d4172d6c39>  173 
     syslogd <7153b590e0353520a19b74a14654eaaa>  178 
      wifid <3001cd0a61fe357d95f170247e5458f5>  319 
    UserEventAgent <dc32e6824fd33bf189b266102751314f>  409 
     launchd <5fec01c378a030a8bd23062689abb07f>  126 

**End** 

A una più attenta ispezione, la memoria sporca consiste principalmente di pagine Image IO e Core Animation. più voci composte da centinaia a migliaia di pagine. Cosa fanno Image IO e Core Animation esattamente? e come posso ridurre la memoria sporca?

edit: provato a fare questo su una coda di serie e nessun miglioramento sulla dimensione della memoria sporco

un'altra domanda. quanto è grande la dimensione della memoria sporca e le allocazioni?

Aggiornato:

- (void) render 
{ 
    for (id thing in mylist) { 
     @autorelease { 
      CALayer *layer = createLayerFromThing(thing); 
      UIImage *img = [self renderLayer:layer]; 
      [self writeToDisk:img]; 
     } 
    } 
} 

a createLayerFromThing (cosa); In realtà creando uno strato con una grande quantità di strati sub

AGGIORNAMENTO

prima schermata per maxConcurrentOperationCount = 4

secondo per maxConcurrentOperationCount = 1

maxConcurrentOperationCount = 4

maxConcurrentOperationCount = 1

================================================ ================================================== ================================================== ========

e dal momento che ridurre il numero di operazioni simultanee a malapena ha fatto un'ammaccatura, ho deciso di provare maxConcurrentOperationCount = 10

maxConcurrentOperationCount = 10

+0

ImageIO viene utilizzato da iOS per decodificare le immagini. Hai a che fare con immagini ad alta risoluzione o utilizzando un gran numero di immagini? – Jorge

+0

Sto usando un gran numero di CALayer e li rasterizzo – tzl

+0

Qual è la risoluzione dell'immagine finale? – Jorge

risposta

4

e 'difficile dire che cosa è andare storto senza dettagli ma ecco alcune idee.

A. Utilizzare @autorelease. I CALayer generano bitmap nel backgound, che in aggregato possono occupare molto spazio se non vengono liberati in tempo. Se stai creando e eseguendo il rendering di molti layer, ti suggerisco di aggiungere un blocco di autorelease all'interno del tuo ciclo di rendering. Questo non aiuterà se TUTTI i tuoi livelli sono nidificati e necessari allo stesso tempo per il rendering.

- (void) render 
{ 
    for (id thing in mylist) { 
     @autorelease { 
      CALayer *layer = createLayerFromThing(thing); 
      [self renderLayer:layer]; 
     } 
    } 
} 

B. Anche se si utilizza CGBitmapCreateContext per il rendering stai chiamando il CGContextRelease corrispondenza? Questo vale anche per CGColorRef.

C. Se si assegna memoria con malloc o calloc, lo si libera alla fine?Un modo per garantire che ciò avvenga

Inviare il codice per il ciclo di rendering per fornire più contesto.

+0

A. sì, io uso Autorelease B & C si è verificato per perdite di memoria e crescita dell'heap accuratamente – tzl

+0

Quanti strati di quali dimensioni utilizza lo scenario di test? – aLevelOfIndirection

+0

un indicatore di rouge (perché ci sono così tanti oggetti) a circa ~ 200 KB per ogni livello (con tutti i sottolivelli) che sto rasterizzando. Sto pensando che potrebbe richiedere un sacco di memoria virtuale per elaborare CALayers – tzl

2

Credo che ci siano due possibilità:

  1. Le voci create non sono autoreleased.
  2. La memoria che si sta prendendo è quella che è, a causa del numero di operazioni simultanee che si stanno facendo.

Nel primo caso la soluzione è semplice. Invia un messaggio autorelease ai livelli e alle immagini al momento della loro creazione.

Nel secondo caso, è possibile limitare il numero di operazioni simultanee utilizzando uno NSOperationQueue. Le code di operazioni hanno una proprietà denominata maxConcurrentOperationCount. Vorrei provare con un valore di 4 e vedere come il comportamento della memoria cambia da quello che hai attualmente. Naturalmente, potrebbe essere necessario provare valori diversi per ottenere il giusto equilibrio tra memoria e prestazioni.

+0

Questo è quello che credevo e riducendo al minimo il numero di operazioni simultanee si riducono le allocazioni. ma è così poco che non fa differenze significative rispetto alla memoria virtuale: / – tzl

0

Autorelease attenderà fino alla fine del ciclo di esecuzione per pulire. Se si rilascia esplicitamente, può prenderlo dall'heap senza riempire la piscina.

- (void) render { 
    for (id thing in mylist) { 
     CALayer *layer = createLayerFromThing(thing); // assuming this thing is retained 
     [self renderLayer:layer];       
     [layer release];         // this layer no longer needed 
    } } 

Eseguire anche build con analizzare e vedere se si dispone di perdite e risolvere anche loro.

Problemi correlati