5

J2ME Web ブラウザ アプリケーションを開発しましたが、正常に動作しています。そのメモリ消費量をテストしています。メモリ モニター (ワイヤレス ツールキットの) の消費メモリを表す緑色の曲線が、ブラウザによって 7 回のリクエストが行われるたびに割り当てられた最大メモリ (687768 バイト) に達するため、メモリ リークがあるように思えます (つまり、エンド ユーザーが Web ブラウザーで 7 ページ間、あるページから別のページに移動したとき)、その後、ガベージ コレクターが実行され、割り当てられたメモリが解放されます。

私の質問は:

  • ガベージ コレクタが 7 ページ ナビゲーションごとに自動的に実行されると、メモリ リークですか?
  • 割り当てられた最大メモリに達するのを防ぐために、ガベージ コレクタ (System.gc()) をリクエストごとに 1 回手動で実行する必要がありますか?

私を案内してください、ありがとう

4

5 に答える 5

3

メモリ リークであるかどうかを判断するには、さらに観察する必要があります。

あなたの説明から、つまり、最大メモリに達すると、GC が作動し、アプリケーションを実行するためにメモリを解放できるようになります。リークがあるようには聞こえません。

また、GC を自分で呼び出さないでください。

  1. それは単なる目安です
  2. パフォーマンスに影響を与える基礎となるアルゴリズムに影響を与える可能性があります。

代わりに、アプリケーションがこのような短期間に大量のメモリを必要とする理由に注目する必要があります。

于 2012-09-16T11:19:06.313 に答える
1

私は、GC を強制するための努力をするライブラリを作成しました。前に述べたように、System.gc()は非同期であり、それ自体では何もしません。このライブラリを使用してアプリケーションのプロファイリングを行い、ガベージが大量に生成されている場所を見つけることができます。詳細については、GC の問題について詳しく説明しているこの記事を参照してください。

于 2012-11-23T02:45:41.080 に答える
1

私の質問は、ガベージ コレクターが 7 ページのナビゲーションごとに自動的に実行されるときのメモリ リークですか?

必ずしも。次のことも考えられます。

  • 解決しようとしている問題のサイズに対してヒープが小さすぎる、または

  • アプリケーションが (収集可能な) ガベージを高速で生成しています。

実際、あなたが提示した数値を考えると、これは主にヒープ サイズの問題であると考える傾向があります。GC 実行の間隔が時間の経過とともに減少した場合、それはメモリ リークを示している証拠になりますが、レートが平均して安定している場合は、メモリ使用率と再利用のレートがバランスしていることを示唆しています。つまり、漏れません。

割り当てられた最大メモリに達するのを防ぐために、ガベージ コレクタ (System.gc()) をリクエストごとに 1 回手動で実行する必要がありますか?

ダメダメダメ。

を呼び出しSystem.gc()てもメモリ リークは解決されません。それが実際のメモリ リークである場合、呼び出しSystem.gc()はリークしたメモリを再利用しません。実際、あなたがすることは、アプリケーションの実行を非常に遅くすることだけです... JVMが呼び出しを完全に無視しないと仮定します。


HotSpot JVMのデフォルトの動作が System.gc() 呼び出しを尊重することであるという直接的および間接的な証拠:

そしてJava 7ソースコードから:

./openjdk/hotspot/src/share/vm/runtime/globals.hpp

  product(bool, DisableExplicitGC, false,                                   \
          "Tells whether calling System.gc() does a full GC")               \

ここで、falseはオプションのデフォルト値です。(そして、これはコード ツリーの OS / M/C に依存しない部分にあることに注意してください。)

于 2012-09-16T12:00:43.517 に答える
0

それは(半)正常な動作です。使用可能な (参照されていない) ストレージは、ヒープのサイズがあるしきい値に達して収集サイクルがトリガーされるまで収集されません。

もう少し「ヒープを意識」することで、GC サイクルの頻度を減らすことができます。たとえば、多くのプログラムでよくあるエラーは、substring を使用して文字列を解析し、左端の単語を解析するだけでなく、残りの文字列を右側に部分文字列化して短縮することです。単語の新しい文字列を作成することは簡単に回避できませんが、元の文字列の「末尾」を繰り返しサブストリング化することは簡単に回避できます。

System.GC を実行しても何も達成されません。ほとんどのプラットフォームでは、悪用されることが多いため、何もしません。

(脳死状態の Android 以外では) Java で真の「メモリ リーク」が発生することはありません (深刻な JVM バグがない限り)。Java で一般的に「リーク」と呼ばれるのは、二度と使用されないオブジェクトへのすべての参照を削除できないことです。たとえば、チェーンにデータを入れ続け、使用されなくなったチェーンの遠端にあるものへのポインターを決してクリアしない場合があります。その結果として、使用される最小ヒープ (つまり、GC 実行直後のサイズ) がサイクルごとに増加し続けるという症状が発生します。

于 2012-09-16T12:26:06.357 に答える
0

他の優れた回答に追加:

メモリ リークガベージ コレクションを混同しているようです。

メモリ リークは、未使用のメモリがまだどこかに参照を持っているためにガベージ コレクションできない場合です (ただし、それらは何にも使用されていません)。

ガベージ コレクションとは、ソフトウェア (ガベージ コレクター) が参照されていないメモリを自動的に解放することです。

パフォーマンスに影響するため、ガベージ コレクターを手動で呼び出さないでください。

于 2012-09-16T15:22:26.243 に答える