7

かなりの量のメモリを使用して複雑なシーンをセットアップする OpenGL Android アプリがあり、これが明らかにヒープの断片化を大幅に引き起こします。メモリ リークはありませんが、断片化によるメモリ不足なしにアプリを破棄して作成することは不可能です。(断片化は間違いなく問題であり、リークではありません)

Android には同じ VM/ヒープでアクティビティを破棄および作成する習慣があり、明らかにアクティビティがクラッシュするため、これは大きな問題を引き起こします。これに対抗する戦略として、次の手法を使用しました。

@Override
protected void onStop() {
    super.onStop();
    if(isFinishing()) {
        System.runFinalizersOnExit(true);
        System.exit(0);
    }
}

これにより、アクティビティが終了すると VM が完全にシャットダウンされるため、次にアクティビティが開始されたときにフラグメント化されていない新しいヒープが取得されます。

注: これは「Android のやり方」ではないことは承知していますが、ガベージ コレクターが圧縮されていないことを考えると、ヒープを継続的に再利用することは不可能です。

この手法は実際には一般的に機能しますが、アクティビティが非終了モードで破棄されてから再作成された場合は機能しません。

ヒープの劣化を処理する方法について何か良い提案はありますか?

さらに注意: メモリ消費量を削減することも、実際にはオプションではありません。アクティビティは実際にはそれほど多くのメモリを使用しませんが、ヒープ (およびネイティブ ヒープ) は、おそらく大きなメモリ チャンクが原因で、簡単に断片化されるようです。

4

1 に答える 1

4

断片化は、ほとんどの場合、悪条件の割り当てパターンの結果です。大きなオブジェクトは頻繁に作成および破棄されます。小さいオブジェクトが持続する可能性がある (または、少なくとも存続期間が異なる) ことに関連して、ヒープに穴が作成されます。

このようなシナリオで唯一機能する断片化防止は、特定の割り当てパターンを防止することです。これは、多くの場合、大きなオブジェクトをプールすることで実行できます。成功した場合、アプリケーションはこれを認識し、実行速度も大幅に向上します。

@edit:あなたの質問にさらに具体的に:アプリケーションの再起動後のヒープがまだ空でない場合、ヒープに残るものは何ですか?メモリリークの問題ではないことを確認されましたが、これは、そのようです。OpenGL を使用しているため、OpenGL リソースが適切に破棄されていないため、一部のネイティブ ラッパーが生き残った可能性がありますか?

于 2012-02-28T18:06:31.010 に答える