Android Admob 4.1.1 has a memory leak (see attache

2019-04-11 20:08发布

I have a test project which demonstrates a memory leak caused by Admob 4.1.1.

The basic scenario is I have two activities and I switch back and forth between the main and the sub activity several times. I then switch to DDMS and force a few GCs. Then dump the HPROF and look at the historgram filtered by com.test* to see how many instances of the main and sub activity there are. My screenshots of the histogram are attached:

A leak! leaks

I then commented out the ads in the xml and reran and there were no leaks:

No leak now no leak

I have found some relevant posts to Admob leaks such as here: Android AdMob causes memory leak?

Here is a list of things I have tried to resolve the issue:

  1. Wait some amount of time and then force gc
  2. Do not load the ad in oncreate but spawn a thread to wait then load it
  3. Tried a previous version of Admob (the one not written by Google)
  4. Called adView.destroy() in the onDestroy() activity's method
  5. The unbinding from this link

Obviously none of these things helped.

Here is the test project I wrote:

(Be sure to set your own publisher id when you run the test project)

download test leak android project

If it makes a difference I'm tesing on my SGS2 with Cyanogenmod ROM.

Does this happen for other people when they run this project?

Does anyone know the cause a fix or a workaround?

Thanks

3条回答
Deceive 欺骗
2楼-- · 2019-04-11 20:37

My app uses 80% of the allowed 16Mb and the AdView leaks at every orientation change (since android destroys and recreates the whole activity then). As a result I am out of memory after a dozen or so orientation changes giving me the dreaded:

10-08 10:14:47.178: ERROR/dalvikvm-heap(2876): 1440000-byte external allocation too large for this process.

10-08 10:14:47.178: ERROR/dalvikvm(2876): Out of memory: Heap Size=5191KB, Allocated=2877KB, Bitmap Size=18675KB

10-08 10:14:47.178: ERROR/GraphicsJNI(2876): VM won't let us allocate 1440000 bytes

or similar.

The increase in memory can easily be seen in eclipse by doing a debug run and opening Window > Open perspective > Other > DDMS, clicking the "update heap" icon and doing a Cause GC. The easiest way to check imho is the #Objects. If the orientation has changed from portrait to landscape and back, the number of Objects should be exactly the same (and without AdView it is).

I work around the memory leak by making the AdView static

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);
    }
}

and not calling the destroy

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

At least this prevents memory leaks between every orientation change.

Also I set request to null after using it. Don't know if that helps.

    AdRequest request = new AdRequest();
    mAdView.loadAd(request);
    request = null;
查看更多
Lonely孤独者°
3楼-- · 2019-04-11 20:49

My solution

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);
查看更多
何必那么认真
4楼-- · 2019-04-11 20:51

Yes, I build it all up dynamically. I use removeAllViews to remove all views from my (LinearLayout) container. Then I use addView to put them all back again. The ad is clickable. Is there perhaps some transparent view in front of it in your case?

查看更多
登录 后发表回答