2013-03-19 7 views
5

私は同時に操作を実行するアプリケーションの一部です。多くのCALayersを初期化し、ビットマップにレンダリングします。VM Trackerに大きなダーティーサイズが表示されます

残念ながら、これらの操作中(iphone 4で約2秒かかっています)、VM Trackerで示されるDirty Sizeは約120MBになります。割り当てが〜12MBにスパイク(蓄積しない)私の理解から、ダーティサイズは解放できないメモリです。非常に頻繁に、私のアプリとバックグラウンドの他のすべてのアプリが殺されます。

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

詳細を確認すると、汚れたメモリは主にイメージIOとコアアニメーションページで構成されます。数百から数千ページからなる複数のエントリ。 Image IOとCore Animationは正確に何をしていますか?どうやってダーティーメモリを減らすことができますか?

編集:シリアルキューとダーティメモリ

別の質問の大きさには何の改善にこれをやってみました。ダーティなメモリと割り当てにはどれくらいの大きさが大きすぎますか?

更新:

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

。私は実際に

をmaxConcurrentOperationCount = 1

maxConcurrentOperationCount = 4

maxConcurrentOperationCount = 1

ためmaxConcurrentOperationCount = 4

秒間

最初のスクリーンショットを更新したサブ層の膨大な量の層を作成します

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

、それは同時操作の数はほとんどへこみを作っダウンさせているため、 私はそれが何を言うのは難しいですmaxConcurrentOperationCount = 10

maxConcurrentOperationCount = 10

+0

ImageIOは、画像をデコードするためにiOSによって使用されます。高解像度の画像や多数の画像を扱っていますか? – Jorge

+0

私は大量のCALayersを使用しており、それらをラスタライズしています – tzl

+0

最終的な画像解像度は何ですか? – Jorge

答えて

4

を試してみることにしました詳細は間違っていますが、ここにいくつかのアイデアがあります。

A. @autoreleaseを使用してください。 CALayersはバックグラウンドにビットマップを生成します。バックマップは、時間内に解放されないと、大量の領域を占めることがあります。多くのレイヤーを作成してレンダリングする場合は、レンダリングループの内部に自動解放ブロックを追加することをお勧めします。すべてのレイヤーがネストされ、同時にレンダリングする必要がある場合、これは役に立ちません。

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

B.はまた、あなたが一致CGContextReleaseを呼んでいるレンダリングするためのCGBitmapCreateContextを使用している場合は? CGColorRefについても同様です。

C. mallocまたはcallocを使用してメモリを割り当てている場合は、終了すると解放されますか?これを確実にする1つの方法

より多くのコンテキストを提供するために、レンダリングループのコードを掲載してください。

+0

A.はい私はAutoreleaseを使用しますB&Cはい、メモリリークとヒープの成長を完全にチェックしました – tzl

+0

テストシナリオはどのくらいのサイズのレイヤーを使用しますか? – aLevelOfIndirection

+0

私はラスタライズしている各レイヤー(すべてのサブレイヤを含む)に対して約200KBのルージゲージ(非常に多くのオブジェクトが存在するため)です。私はそれがちょうど多くを取るかもしれないと思っていますCALayersを処理するために多くの仮想メモリ – tzl

2

私は2つの可能性がここにあると信じて:

  1. は、あなたが作成したアイテムが自動解放されていません。
  2. あなたが行っているメモリは、実行中の同時操作の数のためです。

最初のケースでは解決策は簡単です。作成時にレイヤーと画像にautoreleaseメッセージを送信します。

NSOperationQueueを使用すると、同時操作数を制限できます。操作キューにはmaxConcurrentOperationCountというプロパティがあります。私は4の値で試して、あなたの現在のものからどのようにメモリの動作が変わるかを見てみましょう。もちろん、適切なメモリとパフォーマンスのバランスを得るためには、異なる値を試す必要があります。

+0

これは私が信じていたことであり、同時に実行される操作の数を最小限にすることによって割り当てが失われます。しかし、仮想メモリにはそれほど大きな違いはありません: – tzl

0

自動解放は、実行ループの終了がクリーンアップするまで待機します。あなたが明示的にリリースすれば、プールを満たさずにヒープから取り出すことができます。

- (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 
    } } 

また、analyzeを使用してビルドを実行し、漏れがあるかどうか確認して修正してください。

関連する問題