3

我有一个测试项目,它演示了 Admob 4.1.1 引起的内存泄漏。

基本场景是我有两个活动,我在主活动和子活动之间来回切换几次。然后我切换到 DDMS 并强制执行一些 GC。然后转储 HPROF 并查看由 com.test* 过滤的直方图,看看有多少主活动和子活动实例。附上我的直方图截图:

泄漏! 泄漏

然后我将 xml 中的广告注释掉并重新运行,没有泄漏:

现在没有泄漏 无泄漏

我发现了一些与 Admob 泄漏相关的帖子,例如:Android AdMob 导致内存泄漏?

以下是我尝试解决此问题的清单:

  1. 等待一段时间,然后强制 gc
  2. 不要在 oncreate 中加载广告,而是生成一个线程等待然后加载它
  3. 尝试了以前版本的 Admob(不是由 Google 编写的)
  4. 在 onDestroy() 活动的方法中调用 adView.destroy()
  5. 从此链接解除绑定

显然,这些东西都没有帮助。

这是我写的测试项目:

(运行测试项目时一定要设置自己的发布者ID)

下载测试泄漏android项目

如果它有所作为,我正在使用 Cyanogenmod ROM 在我的 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): 内存不足: 堆大小 = 5191 KB, 已分配 = 2877 KB, 位图大小 = 18675 KB

10-08 10:14:47.178: 错误/GraphicsJNI(2876): VM 不允许我们分配 1440000 字节

或类似的。

通过执行调试运行并打开 Window > Open perspective > Other > DDMS,单击“更新堆”图标并执行 Cause GC,可以很容易地在 Eclipse 中看到内存的增加。检查恕我直言的最简单方法是#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;
}

至少这可以防止每次方向更改之间的内存泄漏。

我也在使用它后将请求设置为空。不知道这是否有帮助。

    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 回答