3

Admob4.1.1によって引き起こされたメモリリークを示すテストプロジェクトがあります。

基本的なシナリオは、2つのアクティビティがあり、メインアクティビティとサブアクティビティを数回切り替えることです。次に、DDMSに切り替えて、いくつかのGCを強制します。次に、HPROFをダンプし、com.test *でフィルタリングされたヒストリグラムを調べて、メインアクティビティとサブアクティビティのインスタンスがいくつあるかを確認します。ヒストグラムのスクリーンショットが添付されています。

漏れ! リーク

次に、xml内の広告をコメントアウトして再実行しましたが、リークはありませんでした。

今リークはありません 漏れなし

私はここのようなAdmobリークに関連するいくつかの投稿を見つけました:Android AdMobはメモリリークを引き起こしますか?

これが私が問題を解決しようとしたことのリストです:

  1. しばらく待ってから、gcを強制します
  2. oncreateに広告をロードせずに、スレッドを生成して待機してからロードします
  3. 以前のバージョンのAdmob(Googleによって作成されていないもの)を試しました
  4. onDestroy()アクティビティのメソッドでadView.destroy()を呼び出しました
  5. このリンクからのバインド解除

明らかに、これらのことのどれも役に立ちませんでした。

これが私が書いたテストプロジェクトです:

(テストプロジェクトを実行するときは、必ず独自の発行元IDを設定してください)

テストリークAndroidプロジェクトをダウンロード

それが違いを生むなら、私はCyanogenmodROMを使ってSGS2を試してみています。

他の人がこのプロジェクトを実行するときに、これは起こりますか?

誰かが原因を知っていますか?修正または回避策はありますか?

ありがとう

4

3 に答える 3

2

私のアプリは許可された16Mbの80%を使用し、向きが変わるたびにAdViewがリークします(Androidはアクティビティ全体を破棄して再作成するため)。その結果、私は十数かそこらの向きが変わった後、私に恐ろしいことを与えて記憶がなくなりました:

10-08 10:14:47.178:エラー/ dalvikvm-heap(2876):このプロセスには1440000バイトの外部割り当てが大きすぎます。

10-08 10:14:47.178:エラー/ dalvikvm(2876):メモリ不足:ヒープサイズ= 5191KB、割り当て済み= 2877KB、ビットマップサイズ= 18675KB

10-08 10:14:47.178:ERROR / GraphicsJNI(2876):VMで1440000バイトを割り当てられません

または類似。

メモリの増加は、デバッグを実行して[ウィンドウ]>[パースペクティブを開く]>[その他]>[DDMS]を開き、[ヒープの更新]アイコンをクリックして、Cause GCを実行することで、Eclipseで簡単に確認できます。imhoをチェックする最も簡単な方法は、#Objectsです。向きが縦向きから横向き、そし​​て後ろ向きに変わった場合、オブジェクトの数はまったく同じである必要があります(AdViewがない場合は同じです)。

AdViewを静的にすることでメモリリークを回避します

private static AdView mAdView = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(mAdView == null)
    {
        mAdView = new AdView(this, AdSize.BANNER, ADMOB_PUBLISHER_ID);
    }
}

破壊を呼び出さない

@Override
public void onDestroy() {
    super.onDestroy();
    //mAdView.destroyDrawingCache();
    //mAdView.destroy();
    //mAdView = null;
}

少なくともこれにより、向きを変えるたびにメモリリークが発生するのを防ぎます。

また、使用後はリクエストをnullに設定しました。それが役立つかどうかわからない。

    AdRequest request = new AdRequest();
    mAdView.loadAd(request);
    request = null;
于 2011-10-09T13:14:53.490 に答える
1

私の解決策

private void destroyWebView(ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
    if (viewGroup.getChildAt(i) instanceof WebView) {
        WebView view = (WebView) viewGroup.getChildAt(i);
        viewGroup.removeView(view);
        view.destroy();
        return;
    }
}
}

@Override
protected void onDestroy() {
mAdView.stopLoading();
destroyWebView(mAdView);
((ViewGroup) mAdView.getParent()).removeView(mAdView);
于 2013-01-15T12:39:13.613 に答える
-1

はい、すべて動的に構築します。removeAllViewsを使用して、(LinearLayout)コンテナからすべてのビューを削除します。次に、addViewを使用してそれらをすべて元に戻します。広告はクリック可能です。あなたの場合、その前に透明な景色があるのでしょうか?

于 2011-10-18T19:38:22.420 に答える