我对AdMob SDK似乎使用了多少内存以及这些内存的实际位置感到困惑。让我解释一下。
我的应用程序有两种版本:免费和付费。免费版有AdMob广告,否则代码几乎相同(使用普通的Android库)。
我在Nexus 4(Android 4.2.1)上运行应用程序并比较内存使用情况。我在设备设置中查看应用程序使用的系统内存>应用程序>运行。我还查看了 GC logcat 消息报告的 Dalvik 堆内存,并使用 HPROF 文件。
当我运行付费版本时,我可以看到:
- 系统内存:约16MB
- 达尔维克堆大小:约10MB
当我运行免费版本时,我可以看到:
- 系统内存:约29MB
- 达尔维克堆大小:约11MB
换句话说,两个版本的 dalvik 堆大小相似。但实际使用的系统内存高出 10MB+!
在花时间学习内存分析 (http://www.youtube.com/watch?feature=player_embedded&v=_CruQY55HOk) 和数小时查看 HPROF 文件以消除任何可能的泄漏之后,我只能看到一个结论:
AdMob 使用的 10MB 额外系统内存实际上是原生内存,使用 malloc 分配,在 dalvik 堆之外!
现在我想知道两件事:
- 我相信由于免费版系统内存大 10MB比付费版,万一更容易作系统杀死的内存压力。还是安卓操作系统只考虑用于决定杀死哪个应用程序的 Dalvik 堆?
- 有没有办法调整AdMob SDK以选择它的内存量允许分配?
AdMob 使用网页视图加载广告。这是一个相当复杂的对象,它使用本机库,并且容易崩溃。AdMob SDK 非常努力地使其易于管理,但您无法真正控制其工作方式。此外,内存使用量可能因广告类型而异:HTML 文本广告与带有图片的横幅广告等。
因此,除非您愿意对AdMob进行二进制补丁(它不是开源的),否则您只需要忍受它。您可以主动移除和销毁AdView
以减少任何泄漏,但您无能为力。
使用 2 种不同的 AdMob 实现方式测试我的应用后,我发现通过 java 代码而不是 XML 实现它与该应用程序的匹配更轻。
更新No1:
您还可以添加自定义侦听器以在一段时间后销毁并重新创建,以便更好地处理它。服务器端还有一个参数告诉应用程序广告应该多久要求一个新广告,我不确定它是否在所有情况下都存在,但它适用于 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 删除任何回调,请参阅文档