Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android AdMob memory usage

I'm confused about how much memory AdMob SDK seem to be using, and where this memory is actually located. Let me explain.

I've got two flavors of my app: Free and Paid. Free version has AdMob ads, otherwise the code is almost the same (common Android lib used).

I run the apps on my Nexus 4 (Android 4.2.1) and compare memory usage. I look at system memory used by the app in device settings > apps > running. I also look at the Dalvik heap memory as reported by GC logcat messages, and using HPROF files.

When I run Paid version I can see:

  • System memory: About 16MB
  • Dalvik heap size: About 10MB

When I run the Free version I can see:

  • System memory: About 29MB
  • Dalvik heap size: About 11MB

In other words, the dalvik heap size is similar for both versions. But the actual system memory used is 10MB+ higher!

Having spent time learning about memory profiling (http://www.youtube.com/watch?feature=player_embedded&v=_CruQY55HOk), and hours looking at HPROF files to remove any possible leak, I can only see only one conclusion:

The 10MB extra system memory used by AdMob is actually native memory, allocated using malloc, outside of dalvik heap!

Now I'm wondering about two things:

  1. I believe that since Free version system memory is 10MB bigger than Paid version, it is much more prone to be killed by OS in case of memory pressure. Or does the Android OS only take into account the Dalvik heap for deciding which app to kill?
  2. Is there a way to tune AdMob SDK to select how much memory it is allowed to allocate?

Thank's a lot

like image 802
gpo Avatar asked Jan 29 '13 13:01

gpo


2 Answers

AdMob uses a WebView to load ads. That is quite a complex object which makes use of native libraries, and is prone to crashes. The AdMob SDK tries quite hard to make it manageable, but you don't really have any control over how it works. Additionally, memory usage will probably vary by ad type: HTML text ones vs banners with images, etc.

So, unless you are willing to binary-patch AdMob (it's not open source), you just have to live with it. You can remove and destroy AdView's proactively to reduce any leaks, but not much more you can do.

like image 107
Nikolay Elenkov Avatar answered Nov 05 '22 05:11

Nikolay Elenkov


Having test my app with 2 different implementations of AdMob I found that implementing it via java code and not XML is match lighter for the app.

Update No1:

You can also add custom listeners to destroy after some time and recreate in order to handle it even better. Serverside there is also a parameter telling the app ad how soon should ask for a new ad, I am not sure if it exist in all cases but it is there for DFP accounts.

A nice suggested way to implement the ad is that:

new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
    if (!isBeingDestroyed) {
        final AdRequest adRequest = new AdRequest();
        final AdView adView = (AdView) findViewById(R.id.ad);
        adView.loadAd(adRequest);
    }
}).sendEmptyMessageDelayed(0, 1000);

also do not forget to call adView.destroy() onDestroy() activity or when you do not want it any more!

The above way is mentioned here with many useful memory releases!


Update No2: (improvement at Update No1)

An improvement to the suggested handler way. Using that way you avoid (I hope) the handler callbacks that may be stacked when intentionally an activity created/destroyed before the delayed message is send. This is more likely to happen if you decide increase 1000 milliseconds:

Create a Field for the handler:

private adHandler;

At your onCreate:

adHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if (!isBeingDestroyed) {
            final AdRequest adRequest = new AdRequest();
            final AdView adView = (AdView) findViewById(R.id.ad);
            adView.loadAd(adRequest);
        }
        return false;
    }
});
adHandler.sendEmptyMessageDelayed(0, 1000);

At your onDestroy do not forget to "release" the handler:

adHandler.removeCallbacksAndMessages(null); 

null removes any callbacks see doc

like image 31
madlymad Avatar answered Nov 05 '22 04:11

madlymad