11

非常に奇妙な現象が発生しています(テストデバイス:HTC Desire HD、Android 2.3.5)。私はそれSystem.gc()が不必要で落胆していることを知っています、そして私は他のことを提案しようとはしませんが、要点はそれが問題を引き起こしてはならないということです(つまりそれはせいぜい役に立たないはずです)。

GLSurfaceViewビュー階層にを含むアプリケーションがあります。がインスタンス化され、GLSurfaceViewに追加されますActivity.onCreate()。通常、アプリケーションは次のように機能します。

  1. ユーザーがアプリを起動し、メインメニューに移動します
  2. GLSurfaceViewユーザーは、を設定するメインメニュー項目を選択しますView.VISIBLE
  3. ユーザーは組み込みのゲームで遊ぶGLSurfaceView
  4. ユーザーはメインメニューに移動し、アクティビティを終了します(=>Activity.finish()が呼び出されます)

Activity.onPause()はこのように見えます:

mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread

これまでのところ、すべてが正常に機能しています。ただし、次のコードを追加すると問題が発生しますonPause()(ユーザーがメインメニューからゲームを終了する場合)。

mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread    
if (isFinishing()) {
    System.gc();
}

詳細:が初めてActivity開始された場合(つまり、アプリプロセスが以前に存在していなかった場合)、すべてが正常に機能します。ただし、アクティビティの2番目の開始(=メインメニューの最初の終了後、つまり最初の終了後)から開始すると、GLSurfaceViewのフレームレートが40〜50%低下し、組み込みのゲームが遅くなります。Activity.finish()

System.gc()電話を切ると問題はなくなります。さらに、次のことを行うと、問題も解消されます。

mGameThread.pause(); // gameThread is my custom thread class for the in-built game
mGLView.onPause(); // pause the renderer thread
if (isFinishing()) {
    // 1. get layout root of View hierarchy

    // 2. recursively remove (detach) all Views

    // 3. call GC
    System.gc();
}

複雑なため具体的なコードは追加しなかったので、コメントを使用しました。GLSurfaceViewビアを外すだけremoveView()では足りません。ビュー階層全体をクリアする必要があります。

メモリリークが見つからなかったことに注意してください(ドローアブル/スタティックなどによるアクティビティリークはありません)。さらに、もちろん、アプリを閉じるとgameThreadは適切に終了します(ソースコードを含めなかっただけです)。

何かアイデアはありますか?どうやら、System.gc()Androidのアクティビティ/レイアウト破壊メカニズムにいくつかの問題を引き起こしているようです。繰り返しますが、私が言ったように、私が削除するSystem.gc()と、問題は消えます。

4

1 に答える 1

7

Android ゲーム プログラミングの経験があります。System.gc() を呼び出すとスレッドを実行するときに、system.gc() を呼び出してもこのビューが参照されない場合があるため、階層内のすべてのビューをクリアしていました。削除され、このゲームを何度もプレイし続けると、ヒープ メモリが増加し始めていることに気付くでしょう。

これはメモリ リークに依存します。KB メモリがリークしている場合、ゲームがクラッシュするまでにより多くの時間がかかります。Eclipse Memory Anlyser (Eclipse MAT)を使用してスタックを比較するのが最善の方法です。

ステップ 1: ゲームを初めて開始するときにメモリ スナップ ショットを取得する ステップ2: ゲームを 2 回目に開始する ときにメモリ スナップ ショットを取得する ステップ 3: スナップショットの両方のスタックを比較すると、違いがわかり ます。

とても便利なツールです。ゲームのApache Attackで大きなメモリの問題が発生していました。この素晴らしいツールを使用してそれらを修正しました。このECLIPSE MAT TUTORIALに従ってください

于 2012-09-18T07:14:19.250 に答える