0

私の Android アプリでは、大きな int 配列を割り当てています。これにより、十分なメモリがあるはずだと思われるときに、OutOfMemory エラーが発生することがあります。これは私が得るものの例です:

// always this value
ActivityManager.some_instance.getMemoryClass() = 128 Mb

// always this value
Runtime.getRuntime().maxMemory()/(1024*1024) = 128 Mb

// example value
Runtime.getRuntime().freeMemory()/(1024*1024) = 81 Mb

// example value, can also be bigger than freeMemory()
arrayLengthToAllocate*4/(1024*1024) = 47 Mb 

明確にするために、最後の値が freeMemory() より大きいか小さい状況で OutOfMemory エラーが発生します。

エラーが発生するのはなぜですか? 割り当て時にヒープサイズが増えていませんか? 割り当てを試みる直前のアプリのメモリ使用量は約 8 MB であるため、問題になることはありません。

PS。このアプリが行っていることの int[] を使用する以外のアプローチは不可能です。

4

3 に答える 3

1

一般的に言えば、ほとんどのデバイスには、使用できるメモリ量に上限があります。当初、これはアプリケーションごとに 16MB に設定されていたことを知っています。それ以来、これは増加していると思いますが、それでも考慮に入れる必要があるものです.

また、アプリケーションのフットプリントが変動する可能性があること、および Android オペレーティング システムがリソースを競合している他のアプリケーションにもメモリを提供する必要があることを心に留めておく必要があります。Android がアプリケーションをリソースを大量に消費していると認識し、そのリソースを削減している可能性があります。

47MB の整数をメモリに格納することは、アプリケーションのメモリを有効に活用することはできません。より簡単な方法はありませんか? なぜそんなに多くの整数をすぐに利用できるようにする必要があるのか​​ わかりません。確かに整数をSQLiteデータベースに追加し、必要に応じてそれらを読み込んで、メモリ要件の大部分をRAMから物理メモリに移動することは、より良いアプローチでしょうか?

OutOfMemory エラーが発生した場合は、通常、少し欲張りすぎていることを示しており、エラーを制限する最善の方法は、実行していることを縮小して、別のアプローチを見つけることです。

于 2012-11-23T17:16:31.647 に答える
0

問題はヒープの断片化であることがわかりました。デフラグには制限があり、ヒープ内に単一の大きな配列を収めるのに十分な空き連続バイトがないだけです。データを2次元配列に再構築しました。これにより、各行がヒープ内に独自の位置を持っているため、問題が解決します。欠点は、配列からのデータの取得が少し遅くなることです。

于 2012-11-25T10:52:49.023 に答える
0

取得するメモリ量は、システムメモリ サイズです。各アプリケーションには、いくつかのシステム変数に依存する限定されたサブセットがあります。一般的には 16 ~ 32 MB 程度ですが、タブレットの場合は少し大きいこともあります。

于 2012-11-23T17:16:40.300 に答える