2013-03-19 12 views
5

Es gibt einen Teil meiner App, wo ich Operationen gleichzeitig ausführen. Sie bestehen darin, viele CALayers zu initialisieren und sie zu Bitmaps zu rendern.VM Tracker zeigt große Schmutzige Größe

Leider, während dieser Operationen (jeder dauert etwa 2 Sekunden auf einem iPhone 4), die schmutzige Größe von VM Tracker Spikes auf ~ 120MB. Zuteilungen spike auf ~ 12MB (akkumuliert nicht) Aus meinem Verständnis ist die Dirty-Größe Speicher, der nicht freigegeben werden kann. so oft wird meine App und alle anderen Apps im Hintergrund getötet.

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** 

Bei näherer Betrachtung besteht der schmutzige Speicher hauptsächlich aus Image IO- und Core Animation-Seiten. mehrere Einträge, bestehend aus Hunderten oder Tausenden von Seiten. Was genau macht Image IO und Core Animation? und wie kann ich das Dirty Memory reduzieren?

edit: versuchte, tun dies auf eine serielle Warteschlange und keine Verbesserung auf Größe von Dirty Speicher

eine andere Frage. Wie groß ist zu groß für Dirty Memory und Allokationen?

Aktualisiert:

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

in createLayerFromThing (Sache); I Schaffung tatsächlich eine Schicht mit einer großen Menge an Unterschichten

UPDATED

ersten Bildschirm für maxConcurrentOperationCount = 4

Sekunden für maxConcurrentOperationCount = 1

maxConcurrentOperationCount = 4

maxConcurrentOperationCount = 1

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

und da sie die Anzahl der gleichzeitigen Operationen der Senkung kaum eine Delle gemacht, ich versuche zu entscheiden maxConcurrentOperationCount = 10

maxConcurrentOperationCount = 10

+0

ImageIO wird von iOS zum Dekodieren von Bildern verwendet. Haben Sie es mit hochauflösenden Bildern zu tun oder verwenden Sie eine große Anzahl von Bildern? – Jorge

+0

Ich verwende eine große Anzahl von CALayers und rasterisiert sie – tzl

+0

Was ist die endgültige Bildauflösung? – Jorge

Antwort

4

es ist schwer zu sagen, was ist falsch gehen ohne Details, aber hier sind ein paar Ideen.

A. Verwenden Sie @autorelease. CALayers erzeugen Bitmaps im Backgound, die insgesamt viel Speicherplatz belegen können, wenn sie nicht rechtzeitig freigegeben werden. Wenn Sie viele Ebenen erstellen und rendern, schlage ich vor, einen AutoRelease-Block innerhalb Ihrer Rendering-Schleife hinzuzufügen. Dies hilft nicht, wenn ALLE Ihre Ebenen verschachtelt und gleichzeitig zum Rendern benötigt werden.

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

B. Auch wenn Sie CGBitmapCreateContext zum Rendern verwenden, rufen Sie die entsprechende CGContextRelease auf? Dies gilt auch für CGColorRef.

C. Wenn Sie Speicher mit malloc oder calloc zuweisen, geben Sie es frei, wenn Sie fertig sind?Eine Möglichkeit, um sicherzustellen, dass dies geschieht

Veröffentlichen Sie den Code für die Rendering-Schleife, um mehr Kontext bereitzustellen.

+0

A. yep Ich benutze Autorelease B & C ja überprüft auf Speicherlecks und häuft Wachstum gründlich – tzl

+0

Wie viele Ebenen, welche Größe verwendet Ihr Testszenario? – aLevelOfIndirection

+0

ein Rouge-Messgerät (weil es so viele Objekte gibt) bei ca. ~ 200KB für jede Ebene (mit allen Sublayern), die ich rasiere. Ich denke, dass es viel mehr virtuellen Speicher aufnehmen kann, um CALayers zu verarbeiten – tzl

2

Ich glaube, es gibt zwei Möglichkeiten:

  1. Die Elemente, die Sie schaffen nicht Autoreleased werden.
  2. Der Speicher, den Sie gerade verwenden, ist aufgrund der Anzahl gleichzeitiger Operationen, die Sie gerade ausführen.

Im ersten Fall ist die Lösung einfach. Senden Sie eine Nachricht autorelease an die Ebenen und Bilder bei ihrer Erstellung.

Im zweiten Fall können Sie die Anzahl gleichzeitiger Vorgänge mithilfe eines NSOperationQueue begrenzen. Operationswarteschlangen haben eine Eigenschaft namens maxConcurrentOperationCount. Ich würde versuchen mit einem Wert von 4 und sehen, wie das Speicherverhalten sich von dem ändert, was Sie derzeit haben. Natürlich müssen Sie möglicherweise verschiedene Werte ausprobieren, um das richtige Verhältnis zwischen Speicher und Leistung zu erzielen.

+0

Das ist, was ich glaubte, und die Minimierung der Anzahl der gleichzeitigen Operationen bringen Zuweisungen. aber es ist so wenig, dass es keinen signifikanten Unterschied zum virtuellen Speicher macht: / – tzl

0

Autorelease wartet bis zum Ende der Laufschleife aufzuräumen. Wenn Sie explizit freigeben, kann es aus dem Heap nehmen, ohne den Pool zu füllen.

Führen Sie auch Build mit Analyse und sehen Sie, ob Sie Lecks haben und sie auch beheben.

Verwandte Themen