22

我对AdMob SDK似乎使用了多少内存以及该内存实际位于何处感到困惑。让我解释。

我的应用程序有两种风格:免费和付费。免费版有 AdMob 广告,否则代码几乎相同(使用常见的 Android 库)。

我在 Nexus 4 (Android 4.2.1) 上运行应用程序并比较内存使用情况。我在设备设置 > 应用程序 > 运行中查看应用程序使用的系统内存。我还查看了 GC logcat 消息报告的 Dalvik 堆内存,并使用了 HPROF 文件。

当我运行付费版本时,我可以看到:

  • 系统内存:约16MB
  • Dalvik 堆大小:约 10MB

当我运行免费版本时,我可以看到:

  • 系统内存:约29MB
  • Dalvik 堆大小:约 11MB

换句话说,两个版本的 dalvik 堆大小相似。但实际使用的系统内存要高出 10MB 以上

在花时间学习内存分析 ( http://www.youtube.com/watch?feature=player_embedded&v=_CruQY55HOk ) 和查看 HPROF 文件以消除任何可能的泄漏之后,我只能看到一个结论:

AdMob 使用的 10MB 额外系统内存实际上是本机内存,使用 malloc 分配,在 dalvik 堆之外!

现在我想知道两件事:

  1. 我相信由于免费版系统内存比付费版大10MB,因此在内存压力的情况下更容易被操作系统杀死。还是 Android 操作系统只考虑 Dalvik 堆来决定要杀死哪个应用程序?
  2. 有没有办法调整 AdMob SDK 以选择允许分配多少内存?

非常感谢

4

2 回答 2

14

AdMob 使用 WebView 加载广告。这是一个相当复杂的对象,它使用本地库,并且容易崩溃。AdMob SDK 非常努力地使其易于管理,但您无法真正控制它的工作方式。此外,内存使用量可能会因广告类型而异:HTML 文本与带有图像的横幅等。

因此,除非您愿意对 AdMob 进行二进制补丁(它不是开源的),否则您只需要忍受它即可。您可以主动删除和销毁AdView's 以减少任何泄漏,但您无能为力。

于 2013-01-30T02:20:46.357 回答
9

在使用 2 种不同的 AdMob 实现测试我的应用程序后,我发现通过 java 代码而不是 XML 实现它对应用程序来说更轻松。

更新 1 号:

您还可以添加自定义侦听器以在一段时间后销毁并重新创建,以便更好地处理它。服务器端还有一个参数告诉应用程序广告应该多久请求一个新广告,我不确定它是否在所有情况下都存在,但它适用于 DFP 帐户。

实施广告的一个很好的建议方法是:

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

也不要忘记调用adView.destroy()onDestroy() 活动或当您不再需要它时!

上面的方式在这里提到了很多有用的内存释放!


更新 No2:(更新 No1的改进)

对建议的处理程序方式的改进。使用这种方式,您可以避免(我希望)在发送延迟消息之前故意创建/销毁活动时可能堆叠的处理程序回调。如果您决定增加1000毫秒,则更有可能发生这种情况:

为处理程序创建一个字段:

private adHandler;

在您的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);

在您onDestroy不要忘记“释放”处理程序:

adHandler.removeCallbacksAndMessages(null); 

null 删除任何回调见doc

于 2013-02-04T09:02:51.360 回答