さまざまなAndroidデバイスでは、一貫性のないOutFmemoryがクラッシュします

StackOverflow https://stackoverflow.com/questions/7809909

質問

組み込みのゲームエディターでは、ユーザーがスプライトをレベルに入れることができるため、開始時にすべてのビットマップをロードする必要があるゲームを作成しています。また、レベルは、各レベルに動的にスプライトのグループをロードできるシステムなしでさまざまなスプライトを使用します。

しばらくすると、合計サイズの3.5MBのゲーム内ですでに250以上のPNG画像があります。

このゲームは、オプションを設定することなくBitMapFactory.DecodeStreamを使用してほとんどのスプライト(約200)をロードします。また、アクティビティのXMLレイアウトで参照されている他の約50人があります。

さまざまなデバイスでテストすると、ゲームはメモリが外れてしまうことがありますが、パターンを見つけることができず、たとえば画像のサイズやその数を減らす必要があるかどうかを決定することさえできません。

私が開発した携帯電話では、Android 2.2 24MB VMヒープサイズを使用したHTC Desireは、OOMを実行することはありません。

Android 2.2および40MBのVMヒープサイズを備えたDellストリークは、OOMも実行されません。

Android 2.1および24MBのVMヒープサイズを備えたMotorola Milestoneは、すべてのスプライトを正常にロードしますが、アクティビティの1つを開始するときにImageViewで使用されているいくつかの最後の画像(スタートメニュー)で窒息します。そのようなImageViewsのいくつかをコメントすると、ロードされますが、後で他のアクティビティの1つを窒息させる可能性があります。また、おそらく断片化が異なる発射で異なって発生するため、安定していません。

私の相棒の2.2を持つHTCヒーロー(ヒープサイズは16MBですか?)もクラッシュします。

最も混乱しているのは、Motorolaには24MBがあり、HTCの欲求と同じです。 2.1はメモリ管理の実装を効率的に実装していませんか? (たとえば、より多くの断片化につながりますか?)またはすべてのモトローラの携帯電話のメモリ管理が悪化していますか?では、なぜ2.2のHTCヒーローがクラッシュするのですか? HTCのヒーローよりもHTCの欲望が大きいのは何ですか?

OOMは古い携帯電話で起こっているように見えますが、それは私がこれまでに理解した唯一のことです。

OOMが市場の5%である古い携帯電話でのみ発生している場合、クラッシュレポートを収集し、サポートされているリストからクラッシュしたものをすべて除外するだけで、サポートされているデバイスから2.1またはより具体的なリストを除外できます。それ以外の場合は、すべての画像を一定の要因(例えば1.6)でスケーリングする必要があります。これは、設計とテストに数日と数日かかったすべての45レベルを変更し、GUI要素の再配置などを変更することを意味します。 dまだ確信していませんが、どのデバイスで、EG 2の係数によってビットマップの合計サイズの縮小を減らすことは、OOMを避けるのに十分です。

これに関するアドバイスはありますか? BitMapFactoryの特定のオプションを設定する必要がありますか?ところで、ほとんどの画像には透明なBGピクセルがあり、私が理解している限り、565形式で入手することはできません。

私はここや他の場所で2日間閲覧しましたが、まだ途方に暮れています。

ありがとうございました。

役に立ちましたか?

解決

私はあなたの問題のより単純なバージョンに対処しなければなりませんでした - 私たちは互いに3つの2mpixレイヤーを持っていました、それは驚くことではありませんが、時にはOOMを引き起こしました。

私の場合、互いの上に3つの画像ビューを使用する代わりに、6つのMPIXすべてを常にメモリに保持するのではなく、レイヤーを手動でブレンドしたため、一度に最大4 mpixをメモリに(そして2 mpixのみで2 mpixしか保持していません。 REST」 - アプリケーションでレイヤーが変更されました)。

これは、メモリ(スペース)を獲得するための古典的な時空間のトレードオフ - 犠牲効率(時間)です。あなたがしなければならなかったので、それはやや遅かった recycle() メモリが解放されたことを確認するために、それを完了した後の各ビットマップ。

一貫性のないOOMSに関しては、おそらくゴミ収集に関係しています。ゴミコレクターは非決定的であるため、記憶圧力は非決定的になると仮定できます(GCが最後にキックした時期に応じて)。

短い要約は、メモリの使用に非常に注意しなければならず、それを回避する方法はないということです。 *

* 理論的には、NDKを使用してOSから直接割り当てることにより、Dalvikヒープの外側にメモリを割り当てることができます。それは巨大なハックであり、ダルヴィクとあなたのアロケーターの間の橋はかなり醜いでしょう。

他のヒント

まず、すべてのメモリを使用しているものを正確に見つける必要があります。 これをチェックしてください。 たとえば、ビットマップをリサイクルしている可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top