5

同時に操作を実行するアプリの一部があります。それらは、多くの CALayer を初期化し、それらをビットマップにレンダリングすることで構成されています。

残念ながら、これらの操作中 (iPhone 4 で完了するのにそれぞれ約 2 秒かかります)、VM トラッカーによって示されるダーティ サイズは最大 120MB に急増します。割り当てが最大 12MB に急増する (蓄積されない) 私の理解では、Dirty サイズは解放できないメモリです。多くの場合、私のアプリとバックグラウンドの他のすべてのアプリが強制終了されます。

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

詳しく調べると、ダーティ メモリはほとんどが Image IO ページと Core Animation ページで構成されています。数百から数千ページからなる複数のエントリ。Image IO と Core Animation は正確には何をしますか? どうすればダーティメモリを減らすことができますか?

編集:シリアルキューでこれを試してみましたが、ダーティメモリのサイズは改善されませんでした

別の質問です。ダーティメモリと割り当てには大きすぎますか?

更新しました:

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

in createLayerFromThing(物); 実際に大量のサブレイヤーでレイヤーを作成している

更新しました

maxConcurrentOperationCount = 4 の最初のスクリーンショット

maxConcurrentOperationCount = 1 の秒

maxConcurrentOperationCount = 4

maxConcurrentOperationCount = 1

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

同時操作の数を減らすことでほとんどへこみがなくなったので、 maxConcurrentOperationCount = 10 を試すことにしました

maxConcurrentOperationCount = 10

4

3 に答える 3

4

詳細がなければ何が問題なのかを言うのは難しいですが、ここにいくつかのアイデアがあります。

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

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

B. また、レンダリングに CGBitmapCreateContext を使用している場合、対応する CGContextRelease を呼び出していますか? これは CGColorRef にも当てはまります。

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

レンダリング ループのコードを投稿して、より多くのコンテキストを提供します。

于 2013-04-04T15:22:10.357 に答える
2

ここには2つの可能性があると思います:

  1. 作成したアイテムは自動リリースされません。
  2. 実行している同時操作の数により、使用しているメモリはそのままです。

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

2 番目のケースでは、を使用して同時操作の数を制限できますNSOperationQueue。オペレーション キューには、 というプロパティがありますmaxConcurrentOperationCount。値を 4 にしてみて、メモリの動作が現在のものからどのように変化するかを確認します。もちろん、適切なメモリとパフォーマンスのバランスを得るために、さまざまな値を試す必要があるかもしれません。

于 2013-04-06T18:22:40.840 に答える