6

LWUITを使用してMIDletを作成していますが、画像が大量のメモリを消費しているようです。私が使用するすべての画像はPNGであり、JARファイル内にパックされています。標準のImage.createImage(URL)メソッドを使用してそれらをロードします。アプリケーションにはいくつかのフォームがあり、それぞれにボタンのラベルがいくつかありますが、アクティブなフォームのみがメモリに保持されていることはかなり確信しています(信頼性が低いことはわかっていますが、Runtime.freeMemory()は確認しているようです)これ)。

アプリケーションは240x320の解像度で正常に動作しましたが、480x640に移動し、UIに適切に大きい画像を使用すると、メモリ不足エラーが表示されるようになりました。アプリケーションが行うことは、とりわけ、リモートイメージをダウンロードすることです。この時点まで、アプリケーションは正常に動作しているようです。いくつかのPNGをダウンロードしてメインメニューに戻ると、メモリ不足エラーが発生します。当然、メインメニューが使用するメモリの量を調べたところ、かなり衝撃的でした。画像付きの2つのラベルと4つのボタンです。各ボタンには、style.setIcon、setPressedIcon、およびsetRolloverIconに使用される3つの画像があります。画像のサイズは15〜25 KBですが、ボタンごとに使用される3つの画像のうち2つ(合計8つの画像)を削除すると、Runtime.freeMemory()はメモリ使用量が1MB減少しました。

私の見方では、メモリリークがたくさんあるか(私はそうは思わないが、メモリリークが簡単に追跡できることは正確にはわかっていない)、画像処理でひどく間違ったことをしている、または本当に問題はなく、スケールダウンする必要があります。

誰かが提供する洞察を持っているなら、私はそれを大いに感謝します。

4

5 に答える 5

2

通常、モバイル デバイスはメモリが非常に不足しています。したがって、メモリを節約して使用するには、いくつかのトリックを使用する必要があります。

私たちのプロジェクトでも同じ問題があり、このように解決しました。

ダウンロードした画像の場合: 画像を置く場所にキャッシュを作成します。画像が必要な場合は、キャッシュマップにあるかどうかを確認し、ない場合はダウンロードしてそこに置き、ある場合はそれを使用します。メモリがいっぱいの場合は、キャッシュマップ内の最も古いイメージを削除して、再試行してください。

他のリソース イメージの場合: それらを表示できる限りメモリに保持します。表示できない場合は、参照を解除すると、gc がクリーンアップを行います。

お役に立てれば。

于 2010-12-08T11:18:30.390 に答える
1

I had a similar problem with LWUIT at Java DTV. Did you try flushing the images when you don't need them anymore (getAWTImage().flush())?

于 2010-06-08T22:59:01.123 に答える
1

可能な場合はリソースファイルを使用してくださいEncodedImage(リソースファイルはEncodedImageデフォルトで使用されます。そのようなものについてはjavadocを読んでください。他のコメントも正しいです。メモリの量を実際に観察する必要があるということです。RAMの多いAndroid / iOSデバイスでも、複数の画像。

を効果的に排除するスケーリングは避けてくださいEncodedImage

于 2012-02-17T09:18:31.430 に答える
1

ここで発生する可能性のあることがいくつかあります。

  • ガベージ コレクションの前に使用されたメモリを見たことがあるかもしれませんが、これはアプリで使用される実際のメモリとは一致しません。
  • 実行しているサード パーティ コードの一部は、割り当てを最小限に抑えるために内部データ構造をプールしている可能性があります。プーリングは実行可能な戦略ですが、リークのように見えることもあります。その場合、不要なオブジェクトを「閉じる」または「破棄」する API があるかどうかを調べます。
  • 最後に、本当に漏れている可能性があります。この場合、エミュレーター VM で何が起こっているかを詳しく知る必要があります (ただし、電話 VM と必ずしも同じではないことに注意してください)。

エミュレーターがバッキング JVM として JRE 1.6 を使用していることを確認してください。erlyer JDK のランタイム ライブラリを使用する必要がある場合は、-Xbootclasspath:<path-to-rt.jar>.

次に、アプリケーションが見たい状態になったら、実行します%JAVA_HOME%\bin\jmap -dump:format=b,file=heap.bin <pid>(プロセスの ID がわからない場合は、を使用しますjps) 。

これで、JVM ヒープのダンプが得られました。jhat(JDKに付属しているため、少し使いにくい)またはサードパーティのプロファイラー(私の好みはYourKit商用ですが、期限付きの評価ライセンスがあります)で分析できます。

于 2010-02-28T02:34:33.200 に答える
0

JAR から同じイメージを何度もロードすると、個々のイメージごとに 1 つのインスタンスを再利用する代わりに、(同一の内容を持つ) 多くの別個のイメージ オブジェクトが作成される可能性があるという事実について考えましたか? これは私の最初の推測です。

于 2009-09-08T22:38:16.113 に答える