2012-01-24 6 views
3

私はadbのlogcatウィンドウで次のことを見ています:なぜこれらのメモリ割り当て番号が足りないのですか?

01-24 14:40:56.916: E/dalvikvm-heap(24727): 1957200-byte external allocation too large for this process. 
01-24 14:40:56.966: E/GraphicsJNI(24727): VM won't let us allocate 1957200 bytes 
01-24 14:40:56.976: E/dalvikvm(24727): OutOfMemory: max: 50331648(49152 K), total: 39985120(39047 K), alloc: 33659240(32870 K), extAlloc: 8993870(8783 K) 

私は理解していないことは、これらの数字は加算されません理由です(または私はちょうどこれがどのように機能するかを理解していません)。私はOutOfMemory:基本的に最大48MBを見る - 私はそれが最大のヒープサイズだと思う。この文脈では「合計」が何を意味するかは不明ですが、約39MBのように見えます。 2MBの割り当てで失敗しました。なぜそれが失敗しているのか分かりません.9MBの空き容量があるはずです...私はここで何を誤解していますか?

答えて

4

ヒープフラグメンテーションの素晴らしい世界へようこそ。一言で言えば、空きバイトだけでなく、割り当てを満たすために連続したメモリチャンクが必要です。

たとえば、空の1MBヒープを想像してみてください。その1MBの真中に1Kの割り当てがあるとしましょう。空き容量の99.9%を持っていても、連続している必要があるため、約500K以上のものを割り当てることはできません。その1Kの割り当てを周りに移動すると、さらに多くを割り当てることができますが、病理学的なケースでは、割り当て可能なメモリよりもはるかに多くの空きメモリが必要になります。

あなたが2000個の1K割り当てをしようとすると、うまくいくと思います。断片化や他の何かを処理しているかどうかを知ることができます。

+0

したがって、断片化されたメモリを再構成する方法が必要です。 System.gc()はそれを行いますか? – user645402

+0

GCは断片化を減らすことができますが、すべてのメモリ割り当てを移動することはできません。たとえば、現在オペレーティングシステムを呼び出すために使用されているバッファは移動できません。 – twk

+0

それでは、もう1つのことは、少なくともRuntime.maxMemory()によれば、48MBのヒープをサポートしなければならないからです。なぜ新しい割り当てに対応するために自動的にヒープのサイズを増やさないのですか? – user645402

関連する問題