2

HTC Sensation OS 4.0.3 でアプリをテストしています。OutOfMemoryError利用可能なメモリが十分にあるように見えるのに、いくつかのシナリオで sを押す理由がわかりません。

たとえば、この場合、私は自分のアプリをうまく使っていました。約 5 分間放置し、アプリがネットワーク接続と処理スレッドをシャットダウンしたことを確認しました。数分後に画面をオンに戻すと、すぐにクラッシュ ポップアップが表示されました。

以下に、重要と思われるログをリストしてみました。

grep "GC_\|memalloc\|OutOfMemoryError" ~/trace.txt

この特定のケースでは、明らかに 40MB の空きヒープ領域があるときに、130KB バイトのバッファ割り当てが失敗していることを示しています。setContentViewほとんどの場合、onCreate やその他の小さな UI 操作で、小さな割り当てが失敗する場所を他にもたくさん見てきました。

10-05 00:26:32.299 32478 32481 D dalvikvm: GC_CONCURRENT freed 4032K, 73% free 13737K/49187K, paused 3ms+28ms
10-05 00:26:38.105 32478 32481 D dalvikvm: GC_CONCURRENT freed 3812K, 73% free 13481K/49187K, paused 4ms+27ms
10-05 00:26:41.698 32478 32481 D dalvikvm: GC_CONCURRENT freed 3927K, 74% free 13122K/49187K, paused 3ms+26ms
10-05 00:26:45.802 32478 32481 D dalvikvm: GC_CONCURRENT freed 3572K, 74% free 12999K/49187K, paused 3ms+27ms
10-05 00:26:48.365 32478 32481 D dalvikvm: GC_CONCURRENT freed 3563K, 74% free 12844K/49187K, paused 3ms+26ms
10-05 00:26:53.069 32478 32481 D dalvikvm: GC_CONCURRENT freed 3506K, 75% free 12675K/49187K, paused 4ms+55ms
10-05 00:26:57.363 32478 32481 D dalvikvm: GC_CONCURRENT freed 3672K, 75% free 12303K/49187K, paused 3ms+25ms
10-05 00:27:01.447 32478 32481 D dalvikvm: GC_CONCURRENT freed 3344K, 76% free 12180K/49187K, paused 3ms+24ms
10-05 00:27:05.121 32478 32481 D dalvikvm: GC_CONCURRENT freed 3212K, 76% free 12034K/49187K, paused 4ms+69ms
10-05 00:27:10.426 32478 32481 D dalvikvm: GC_CONCURRENT freed 3267K, 76% free 11813K/49187K, paused 4ms+40ms
10-05 00:27:14.340 32478 32481 D dalvikvm: GC_CONCURRENT freed 3184K, 77% free 11578K/49187K, paused 3ms+41ms

At this point the app shuts down its various threads.  

10-05 00:35:52.545   249   410 D dalvikvm: GC_EXPLICIT freed 3223K, 50% free 17332K/34531K, paused 4ms+14ms
10-05 00:38:54.633 32478 32478 D dalvikvm: GC_FOR_ALLOC freed 2627K, 78% free 10904K/49187K, paused 113ms
10-05 00:38:54.633 32478 32478 I dalvikvm-heap: Forcing collection of SoftReferences for 131102-byte allocation
10-05 00:38:54.733 32478 32478 D dalvikvm: GC_BEFORE_OOM freed 5K, 78% free 10899K/49187K, paused 97ms
10-05 00:38:54.733 32478 32478 E dalvikvm-heap: Out of memory on a 131102-byte allocation.
10-05 00:38:54.733 32478 32478 I dalvikvm: "main" prio=5 tid=1 RUNNABLE
10-05 00:38:54.733 32478 32478 I dalvikvm:   | group="main" sCount=0 dsCount=0 obj=0x40ad3490 self=0x40f9d0
10-05 00:38:54.733 32478 32478 I dalvikvm:   | sysTid=32478 nice=0 sched=0/0 cgrp=default handle=1074746568
10-05 00:38:54.733 32478 32478 I dalvikvm:   | schedstat=( 0 0 0 ) utm=4527 stm=381 core=1
10-05 00:38:54.733 32478 32478 I dalvikvm:   at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
10-05 00:38:54.733 32478 32478 I dalvikvm:   at java.nio.MemoryBlock.allocate(MemoryBlock.java:126)
10-05 00:38:54.733 32478 32478 I dalvikvm:   at java.nio.ReadWriteDirectByteBuffer.<init>(ReadWriteDirectByteBuffer.java:46)
10-05 00:38:54.733 32478 32478 I dalvikvm:   at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)
10-05 00:38:54.733 32478 32478 I dalvikvm:   at de.tavendo.autobahn.WebSocketReader.<init>(WebSocketReader.java:98)
<snip>
10-05 00:38:54.743 32478 32478 I dalvikvm: 
10-05 00:38:54.743 32478 32478 E dalvikvm: Out of memory: Heap Size=49187KB, Allocated=10899KB, Limit=49152KB
10-05 00:38:54.743 32478 32478 E dalvikvm: Extra info: Footprint=49187KB, Allowed Footprint=49187KB, Trimmed=32296KB
10-05 00:38:54.743 32478 32478 W dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40ad2228)
10-05 00:38:54.953   249   279 D memalloc: /dev/pmem: Unmapping buffer base:0x5aea5000 size:16502784 offset:14483456
10-05 00:38:54.953   249   279 D memalloc: /dev/pmem: Unmapping buffer base:0x59a63000 size:6197248 offset:4177920
10-05 00:38:54.963   112 24561 D memalloc: /dev/pmem: Freeing buffer base:0x4259d000 size:2019328 offset:4177920 fd:38
10-05 00:38:55.124 24504 24504 D dalvikvm: GC_EXPLICIT freed 367K, 41% free 3128K/5219K, paused 2ms+6ms
10-05 00:38:55.234   112   169 D memalloc: /dev/pmem: Freeing buffer base:0x42f71000 size:2019328 offset:14483456 fd:29
10-05 00:38:55.574 24504 24504 D dalvikvm: GC_EXPLICIT freed 18K, 41% free 3114K/5219K, paused 2ms+3ms
10-05 00:38:55.804 32478 32478 E Crittercism: java.lang.OutOfMemoryError: (Heap Size=49187KB, Allocated=10899KB)
10-05 00:38:56.305 32478 32481 D dalvikvm: GC_CONCURRENT freed 2736K, 78% free 10851K/49187K, paused 3ms+8ms
10-05 00:38:57.256 32478  1947 D dalvikvm: JIT code cache reset in 2 ms (1048548 bytes 3/0)
10-05 00:38:57.266 32478  1947 D dalvikvm: GC_FOR_ALLOC freed 901K, 78% free 10825K/49187K, paused 80ms
10-05 00:38:57.286 32478 32478 E AndroidRuntime: java.lang.OutOfMemoryError: (Heap Size=49187KB, Allocated=10899KB)

これらのログの意味を理解するのに苦労しています - クラッシュが起こっている理由を説明できる人はいますか?

全体的に十分なメモリが必要な場合でも、メモリの断片化により割り当てが失敗する可能性があることを読みました。そうであるかどうかを確認する方法はありますか? もしそうなら、このシナリオに対処するために何ができますか?

GC_CONCURRENT ログは、私のコードが多くの割り当てと割り当て解除を行っていることを示唆しているようです。これは、メモリの断片化理論をサポートしている可能性があります。

  • 私のアプリは、特定の時間に大量のデータをダウンロードします。たとえば、巨大なアカウントの場合、初回ログイン時に 30 ~ 40MB になることがあります。
  • また、その合計に追加される画像についても多くのことを行います. 参考までに、画像の読み込みに Volley を使用し、ネットワークからの繰り返しダウンロードを避けるために、インメモリ (これに使用できるメモリの 1/8 制限) とディスク キャッシュを使用しています。

私の質問がこれに似ていることは知ってますが、OS 4.0 を使用しているため、ビットマップの処理に関するアドバイスは必要ないと思います。そのため、すべてのビットマップ データは通常のヒープに表示されます (つまり、GC_ログに既に含まれているはずです)。行合計)。

4

3 に答える 3

4

ご覧のとおり、「 java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)」でメモリ不足が発生しています。

このページによると:

ダイレクト バッファーは I/O に最適ですが、非ダイレクト バイト バッファーよりも作成コストが高くなる可能性があります。ダイレクト バッファで使用されるメモリは、標準の JVM ヒープをバイパスして、オペレーティング システム固有のネイティブ コードを呼び出すことによって割り当てられます。ホスト オペレーティング システムと JVM の実装によっては、ダイレクト バッファーの設定と破棄は、ヒープ常駐バッファーよりも大幅にコストがかかる可能性があります。ダイレクト バッファのメモリ ストレージ領域は、標準の JVM ヒープの外部にあるため、ガベージ コレクションの対象にはなりません。

したがって、これは、割り当てが Java ヒープではなく、OS のメモリ空間であるという質問に答えます。

Websocket ライブラリを再確認することをお勧めします。または、それらのリーダーを適切に閉じるのを忘れましたか?

于 2013-10-05T02:09:34.453 に答える