问题现象

(该文章,引自零号路的私人博客,本人在浏览框架的开发过程中,用该方式,规避了内存泄露的问题。)

在Android5.1系统中,会发现App存在 WebView 泄漏情况,还比较严重。并且只是发生在 Android 5.1 系统。

GC roots 如下:

每新打开一次这个WebViewActivity,就会发生就会发生一次改Webview实例无法释放,新增一个对象。

上图中的两个 AppSearchWebView实例,就是由于打开了两次导致。

问题分析

出现了这个问题分析起来还是比较简单的,根据这个引用关系,我们可以直观的看到是由于 Appsearch(extends Application)的 mComponentCallbacks 一直在强引用AWComponentCallbacks,导致无法释放。然后AWComponentCallbacks -> AWContents > AppSearchWebView。

通过分析代码发现关键在于 AwContents 这里的 AwComponentsCallbacks 为什么没有释放。

    @Override
    public void onAttachedToWindow() {
        if (isDestroyed()) return;
        if (mIsAttachedToWindow) {
            Log.w(TAG, "onAttachedToWindow called when already attached. Ignoring");
            return;
        }

		......

        mComponentCallbacks = new AwComponentCallbacks();
        mContext.registerComponentCallbacks(mComponentCallbacks);
    }

    @Override
    public void onDetachedFromWindow() {
        if (isDestroyed()) return;
        if (!mIsAttachedToWindow) {
            Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring");
            return;
        }
		......

        if (mComponentCallbacks != null) {
            mContext.unregisterComponentCallbacks(mComponentCallbacks);
            mComponentCallbacks = null;
        }

		......
    }

看这段代码看不出来什么问题,onAttach的时候 register,detach的时候 unregister, 不会存在问题。

但是为什么呢?

难道是由于 if (isDestroyed()) return 这条return引起的?

当调用 Webview.destroy() 后 这个判断 返回true。

我们看下哪里调用了 webview.destroy()

// source from WebViewActivity

@Override
protected void onDestroy() {
    super.onDestroy();

    if (mWebView != null) {
        mWebView.destroy();
    }
}

很多应用应该都是这么做的,包括系统浏览器,在Activity destroy的时候,调用 webview的destroy。并且一直工作的很好。

通过调试发现,确实是由于此调用导致的。onDestroy 发生在 onDetach 之前。

那为什么 android 5.1 之前的代码没有问题呢?

看下代码:

	// AwContents.java

    @Override
    public void onDetachedFromWindow() {
        if (!mIsAttachedToWindow) {
            Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring");
            return;
        }

		......

        if (mComponentCallbacks != null) {
            mContext.unregisterComponentCallbacks(mComponentCallbacks);
            mComponentCallbacks = null;
        }
		......
	}

相对于 5.1 的代码少了那句 if (isDestroyed()) return;

规避方法

  • 解决方案可以:在destroy之前,把webview 从 parent 中 remove 掉,同样可以提前detach。

      protected void onDestroy() {
          if (mWebView != null) {
              ((ViewGroup) mWebView.getParent()).removeView(mWebView);
              mWebView.destroy();
              mWebView = null;
          }
          super.onDestroy();
      }

Android5.1系统WebView内存泄漏场景的更多相关文章

  1. Android内存优化14 内存泄漏常见情况5 特殊对象造成的内存泄漏 WebView内存泄漏

    WebView造成内存泄露 关于WebView的内存泄露,因为WebView在加载网页后会长期占用内存而不能被释放,因此我们在Activity销毁后要调用它的destory()方法来销毁它以释放内存. ...

  2. 安卓android WebView Memory Leak WebView内存泄漏

    Android WebView Memory Leak WebView内存泄漏 在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面 ...

  3. Js中常见的内存泄漏场景

    常见的内存泄漏场景 内存泄漏Memory Leak是指程序中已动态分配的堆内存由于疏忽或错误等原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果.内存泄漏并非指内 ...

  4. js的内存泄漏场景、监控以及分析

    内存泄漏 Q:什么是内存泄漏? 字面上的意思,申请的内存没有及时回收掉,被泄漏了 Q:为什么会发生内存泄漏? 虽然前端有垃圾回收机制,但当某块无用的内存,却无法被垃圾回收机制认为是垃圾时,也就发生内存 ...

  5. Android WebView Memory Leak WebView内存泄漏

    在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面后,即使在包含该webview的Activity的destroy()方法中,使用 ...

  6. JVisualVM 模拟一次内存泄漏场景分析

    首先贴一段内存泄漏的代码并且执行.(内存泄漏:GC回收不掉的实例对象) package com.example.demo.memoryLeakDemo; import com.example.demo ...

  7. 系统剖析Android中的内存泄漏

    [转发]作为Android开发人员,我们或多或少都听说过内存泄漏.那么何为内存泄漏,Android中的内存泄漏又是什么样子的呢,本文将简单概括的进行一些总结. 关于内存泄露的定义,我可以理解成这样 没 ...

  8. 解决Android5.0以下Dialog引起的内存泄漏

    最近项目开发中,开发人员和测试人员均反应在android5.0以下手机上LeakCanary频繁监控到内存泄漏,如下图所示,但凡用到Dialog或DialogFragment地方均出现了内存泄漏. 如 ...

  9. Android开发之漫漫长途 番外篇——内存泄漏分析与解决

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

随机推荐

  1. python之在线平台与量化投资

    0. 第一个量化策略 # 初始化函数,设定基准等等 def initialize(context): set_benchmark('000300.XSHG') g.security = get_ind ...

  2. Android组件化框架设计与实践

    在目前移动互联网时代,每个 APP 就是流量入口,与过去 PC Web 浏览器时代不同的是,APP 的体验与迭代速度影响着用户的粘性,这同时也对从事移动开发人员提出更高要求,进而移动端框架也层出不穷. ...

  3. Python CRM项目三

    1.分页: 分页使用Django内置的分页模块来实现 官方的分页案例 from django.core.paginator import Paginator, EmptyPage, PageNotAn ...

  4. JAVA并发编程学习笔记------FutureTask

    FutureTask是Future和Callable的结合体.传统的代码是这样写的Future f = executor.submit(new Callable()); 然后通过Future来取得计算 ...

  5. jQuery的属性,事件及操作

    1.属性操作 1.1 基本属性操作 $("img").attr("src") 返回文档中所有图像的src属性值 $("img").attr( ...

  6. NumPy快速入门笔记

    我正以Python作为突破口,入门机器学习相关知识.出于机器学习实践过程中的需要,我快速了解了一下NumPy这个科学计算库的使用方法.下面记录相关学习笔记. 简介 NumPy是一个科学计算库.结合Py ...

  7. HDU 3689 Infinite monkey theorem [KMP DP]

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...

  8. 用Spring Tools Suite(STS)开始一个RESTful Web Service

    spring.io官方提供的例子Building a RESTful Web Service提供了用Maven.Gradle.STS构建一个RESTFul Web Service,实际上采用STS构建 ...

  9. 阶段小项目2:显示bin格式图片

    #include<stdlib.h>#include<stdio.h>#include<string.h>#include<error.h>#inclu ...

  10. javascript 回到顶部 动画效果

    上代码: <!DOCTYPE html> <html> <head> <meta content="测试demo" name=" ...