`
iaiai
  • 浏览: 2216877 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android WebView Memory Leak WebView内存泄漏

 
阅读更多
在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面后,即使在包含该webview的Activity的destroy()方法中,使用webview.destroy();webview=null;对内存占回收用还是没有任何效果。有人说,一旦在你的xml布局中引用了webview甚至没有使用过,都会阻碍重新进入Application之后对内存的gc。包括使用MapView有时一会引发OOM,几经周折在网上看到各种解决办法,在这里跟大家分享一下。但是到目前为止还没有找到根本的解决办法,网上也有说是sdk的bug。但是不管怎么样,我们还是需要使用的。

要使用WebView不造成内存泄漏,首先应该做的就是不能在xml中定义webview节点,而是在需要的时候动态生成。即:可以在使用WebView的地方放置一个LinearLayout类似ViewGroup的节点,然后在要使用WebView的时候,动态生成即:
WebView      mWebView = new WebView(getApplicationgContext()); 
LinearLayout mll      = findViewById(R.id.xxx); 
mll.addView(mWebView);

然后一定要在onDestroy()方法中显式的调用
protected void onDestroy() {
      super.onDestroy();
      mWebView.removeAllViews();
      mWebView.destroy()
}

注意: new  WebView(getApplicationgContext()) ;必须传入ApplicationContext如果传入Activity的Context的话,对内存的引用会一直被保持着。有人用这个方法解决了当Activity被消除后依然保持引用的问题。但是你会发现,如果你需要在WebView中打开链接或者你打开的页面带有flash,获得你的WebView想弹出一个dialog,都会导致从ApplicationContext到ActivityContext的强制类型转换错误,从而导致你应用崩溃。这是因为在加载flash的时候,系统会首先把你的WebView作为父控件,然后在该控件上绘制flash,他想找一个Activity的Context来绘制他,但是你传入的是ApplicationContext。后果,你可以晓得了哈。

于是大牛们就Activity销毁后还保持引用这个问题,提供了另一种解决办法:既然你不能给我删除引用,那么我就自己来吧。于是下面的这种方法诞生了:

(作者说这个方法是依赖android.webkit implementation有可能在最近的版本中失败)
public void setConfigCallback(WindowManager windowManager) {
    try {
        Field field = WebView.class.getDeclaredField("mWebViewCore");
        field = field.getType().getDeclaredField("mBrowserFrame");
        field = field.getType().getDeclaredField("sConfigCallback");
        field.setAccessible(true);
        Object configCallback = field.get(null);
 
        if (null == configCallback) {
            return;
        }
 
        field = field.getType().getDeclaredField("mWindowManager");
        field.setAccessible(true);
        field.set(configCallback, windowManager);
    } catch(Exception e) {
    }
}

然后在Activity中调用上面的方法:
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setConfigCallback((WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
}
 
public void onDestroy() {
    setConfigCallback(null);
    super.onDestroy();
}

该反射方法在我的实验中(2.3.6)确实有些用处,在应用内存占用到70M左右的时候会明显释放到50M或者60M然后的释放就有些缓慢,其实就是看不出来了。之前在没使用该方法的时候可能达到120M。

但是!!!我们的应用要求占用内存更低啊,这肿么拌?凉拌么?No。在各种纠结之后,终于找到了终极解决办法!!!该办法适用于我们的需求,在退出WebView的界面之后,迅速回收内存。要问这个方法是什么,不要9999,不要8999,只要你仔细看好下面一句话:那就是为加载WebView的界面开启新进程,在该页面退出之后关闭这个进程。

这一点说了之后,你懂了吧?
但是在这个其中,杀死自己进程的时候又遇到了问题,网上介绍的各种方法都不好使,
killBackgroundProcesses(getPackageName());各种不好用,最后使用System.exit(0);直接退出虚拟机(Android为每一个进程创建一个虚拟机的)。这个肯定不用纠结了,一旦退出,内存里面释放。听涛_哥说QQ也是这么做。

最后英雄要问出处,附上大牛解说引起该问题的出处

这个泄漏出现在external/webkit/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp.中。具体我自己真心没有深入研究。大家有兴趣的话,可以看看哈。
引用
--- a/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
+++ b/Source/WebKit/android/WebCoreSupport/UrlInterceptResponse.cpp
@@ -63,10 +63,10 @@ public:
         JNIEnv* env = JSC::Bindings::getJNIEnv();
         // Initialize our read buffer to the capacity of out.
         if (!m_buffer) {
-            m_buffer = env->NewByteArray(out->capacity());
-            m_buffer = (jbyteArray) env->NewGlobalRef(m_buffer);
+            ScopedLocalRef<jbyteArray> buffer_local(env, env->NewByteArray(out->capacity()));
+            m_buffer = static_cast<jbyteArray>(env->NewGlobalRef(buffer_local.get()));
         }
         int size = (int) env->CallIntMethod(m_inputStream, m_read, m_buffer);
         if (checkException(env) || size < 0)
             return;
         // Copy from m_buffer to out.

而且从这里https://github.com/android/platform_external_webkit/commit/1e3e46a731730c02d916ea805ec4b20191509282这个bug的解决状态。
还有一个问题要说的,也是在WebView使用的时候出现的问题:WebView中包含一个ZoomButtonsController,当使用web.getSettings().setBuiltInZoomControls(true);启用该设置后,用户一旦触摸屏幕,就会出现缩放控制图标。这个图标过上几秒会自动消失,但在3.0系统以上上,如果图标自动消失前退出当前Activity的话,就会发生ZoomButton找不到依附的Window而造成程序崩溃,解决办法很简单就是在Activity的ondestory方法中调用web.setVisibility(View.GONE);方法,手动将其隐藏,就不会崩溃了。在3.0一下系统上不会出现该崩溃问题,真是各种崩溃,防不胜防啊!

最后还有内存泄漏的一些个建议:

In summary, to avoid context-related memory leaks, remember the following:
  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don’t control their life cycle, use a static inner class and make a weak reference to the activity inside

And remember that a garbage collector is not an insurance against memory leaks. Last but not least, we try to make such leaks harder to make happen whenever we can.
分享到:
评论

相关推荐

    BAT面试宝典

    11. 内存管理:在iOS开发中,内存管理曾是一个重要的考量点,需要开发者理解引用计数(Reference Counting)、内存泄漏(Memory Leak)等问题。 12. 安全机制:移动应用的安全性越来越受到重视,理解如何保护应用...

    YOLOv10实时端到端目标检测.zip

    python、yolo、pytorch

    网络安全是指通过技术、管理和法律手段保护网络系统、数据及用户隐私,防止未经授权的访问、攻击和信息泄露,确保可用性、完整性和机密性

    网络安全是通过技术手段、管理策略和法律规范,保护网络系统、数据及用户隐私免受未经授权的访问、攻击或泄露,确保网络服务的可用性、数据的完整性和机密性。其核心内容包括: 1. 技术防护:如防火墙、入侵检测系统(IDS)、加密通信、漏洞修复等。 2. 管理措施:包括安全策略制定、访问控制、安全审计、应急响应等。 3. 法律与合规:遵循《网络安全法》《数据安全法》等法规,保障用户隐私与国家安全。 4. 安全意识:提升用户对钓鱼攻击、密码安全等风险的防范能力。 # 适用人群 - 企业/组织:IT运维人员、安全管理员、开发工程师(需保障业务系统安全)。 - 普通用户:需防范个人信息泄露、网络诈骗等风险。 - 政府与公共部门:确保关键基础设施(如电力、金融、通信)的安全运行。 - 教育领域:学生及教师需了解基础安全知识以应对网络威胁。 # 适用场景及目标 1. 企业场景: - 目标:防御黑客攻击、数据泄露、勒索软件等,保障业务连续性。 - 措施:部署网络隔离、多因素认证、定期渗透测试。 2

    2025年DeepSeek引发广泛关注,大模型应用落地将加速.pdf

    人工智能、大语言模型相关学习资料

    基于C#的调用今日头条API并写入数据库 源码.zip

    需要将源码中的key换成正式的key方可使用

    图像处理_TF-Slim_卫星图像分类_训练模型_1741783746.zip

    图像处理项目实战

    jaxlib-0.4.18-cp312-cp312-win_amd64.whl

    该资源为jaxlib-0.4.18-cp312-cp312-win_amd64.whl,欢迎下载使用哦!

    物联网_Android_Things_车牌识别_HyperLPR4Android_边缘计算.zip

    车牌识别项目

    智慧停车_云计算_C_C_Linux_QT_OpenCV_E_1741774510.zip

    车牌识别项目

    生物医学_清测康居家心率体温检测设备_智能监测_1741166755.zip

    Arduino项目

    小微智慧园区数字化建设方案PPT(35页).pptx

    在当今数字化浪潮中,园区智慧化建设正成为推动区域经济发展和产业转型升级的关键力量。这份园区智慧化解决方案全面展示了如何通过集成大数据、云计算、物联网(IoT)、人工智能(AI)、地理信息系统(GIS)和建筑信息模型(BIM)等前沿技术,为传统产业园区插上数字的翅膀,打造“数字创新”产业园区。 数字技术赋能,重塑园区生态 传统产业园区往往面临运营效率低下、管理粗放、资源利用率不高等问题。而通过智慧化改造,园区可以实现从“清水房”到“精装房”的华丽蜕变。数字化技术不仅提升了园区的运营管理水平,降低了运营成本,还显著增强了园区的竞争力和吸引力。例如,通过构建园区数字模型(CIM),实现了多规数据融合,形成了园区规划“一张图”,为园区管理提供了直观、高效的可视化工具。此外,智能感知设施的应用,如环境监测、能耗监测等,让园区管理更加精细化、科学化。智慧能源管理系统通过实时监测和智能分析,帮助园区实现低碳绿色发展,而综合安防管控系统则通过AI+视频融合技术,为园区安全保驾护航。更有趣的是,这些技术的应用还让园区服务变得更加个性化和便捷,比如园区移动APP,让企业和员工可以随时随地享受园区服务,从会议室预定到智慧公寓管理,一切尽在“掌”握。 智慧运营中心,打造园区大脑 园区智慧化建设的核心在于构建智慧运营中心,这可以看作是园区的“数字大脑”。通过集成物联网服务平台、大数据分析平台、应用开发赋能平台等核心支撑平台,智慧运营中心实现了对园区内各类数据的实时采集、处理和分析。在这个“大脑”的指挥下,园区管理变得更加高效、协同。比如,建设工程项目智慧监管系统,通过基于二三维GIS底图的统一数字化监管,实现了对园区在建工程项目的进度控制、质量控制和安全控制的全方位监管。可视化招商系统则利用CIM模型,以多种方式为园区对外招商推介提供了数字化、在线化的展示窗口。而产业经济分析系统,则通过挖掘和分析产业数据,为园区产业发展提供了有力的决策支持。智慧运营中心的建设,不仅提升了园区的整体运营水平,还为园区的可持续发展奠定了坚实基础。 产业服务升级,激发创新活力 园区智慧化建设不仅关注基础设施和运营管理的升级,更重视产业服务的创新。通过整合平台资源、园区本地资源和外围资源,打造园区服务资源池,为园区内的企业和个人提供了全面的智慧管理、智慧工作和智慧生活服务。特别是工业互联网平台和工业云服务的建设,为园区内的企业提供了轻量化、智能化的生产服务。这些服务涵盖了车间信息化管理、云制造执行、云智能仓储、设备健康管理等多个方面,有效提升了企业的生产效率和竞争力。此外,通过产业经济分析系统,园区还能够对潜在客户进行挖掘、对经销商进行风控、对产品销量进行预测等,为企业的市场营销提供了有力支持。这些创新的产业服务,不仅激发了园区的创新活力,还为区域经济的转型升级注入了新的动力。总之,园区智慧化建设是一场深刻的变革,它正以前所未有的方式重塑着园区的生态、运营和服务模式,为园区的可持续发展开辟了广阔的前景。

    地理信息系统中4326与3857坐标系的特性及其应用场景解析

    内容概要:本文对比了EPSG:4326(WGS 84)坐标系和EPSG:3857(Web Mercator)坐标系的主要特征。4326是一种基于经度和纬度的地理坐标系统(GCS),它的坐标用度作为单位,在地理定位方面有较高准确性。相比之下,3857属于一种投影坐标系统(PCS), 该系统内的坐标用平面直角坐标的X/Y轴以米为单位进行测量,在线地图应用领域尤为普及,但是,在高维度的两极地区则会存在一定的失真。 适用人群:对地理信息系统(GIS)、地图制图以及空间数据有兴趣的技术人员和爱好者。 使用场景及目标:帮助读者明白这两种不同坐标系统的特性和优缺点,以便于正确选择适当的坐标系以满足各种空间数据分析和服务需求,比如创建精准的全球定位系统应用程序或者开发高质量的地图展示网站。 其他说明:理解这两者的区别对于确保地理位置数据准确转换及呈现至关重要。无论是从事地图制作还是相关软件的开发者都需要熟悉这两个坐标系的基础知识。

    这是一个yolo3keras的源码可以用于训练自己的模型.zip

    python、yolo、pytorch

    图像识别_PyTorch_宠物分类_网页应用_1741785391.zip

    图像处理项目实战

    识别车牌的一个小demo.zip

    车牌识别

    小程序 礼物说2.4.2 后台模块+前端小程序源码.zip

    源码介绍 更新动态: 版本号:2.4.2 – 礼物说 修复商品下架前端还显示的问题 版本号:2.4.1 – 礼物说 前端分类更新 版本号:2.3 – 礼物说 更改授权方式 版本号:2.2 – 礼物说 修复送给好友礼物,好友不显示的问题

    机器视觉—AI算法模型介绍.pdf

    人工智能、大语言模型相关学习资料

    OpenRAG:通过上下文检索学习端到端优化RAG

    随着大型语言模型(LLMs) (Zhao et al. 2023; Minaee et al. 2024) 的规模扩大,它们面临着数据瓶颈问题,高质量的互联网数据无法满足日益增长的训练需求。与此同时,下游数据量迅速增加,但由于其实时可用性 (Lei Wang et al. 2024; X.-Y. Liu, Wang, and Zha 2023) 、隐私问题 (Arora et al. 2023) 、许可限制 (Min et al. 2024) 和伦理问题 (Serouis and Sèdes 2024; Ayyamperumal and Ge 2024) ,这些数据通常无法用于预训练。 检索增强生成(RAG) (Lewis et al. 2020; Guu et al. 2020; Gao et al. 2023) 成为解决这一挑战的有希望的方法。RAG 不仅依赖精心整理的互联网数据,还利用信息检索(IR)从外部来源获取相关数据,并将其作为上下文以提高生成质量。这在 RAG 中非常有价值,因为它可以使用快速扩展但通常无法访问的下游数据,这些数据比经过大量处理和严

    基于springboot oracle java-swing 的 职工考勤管理信息系统

    oracle 基于springboot oracle java-swing 的 职工考勤管理信息系统

    清华大学第七弹:DeepSeek助力新时代家庭教育智能化解决方案:从理论到实践

    内容概要:这份由清华大学联合人工智能学院发布、涵盖90页的专业报告,全面介绍了如何利用DeepSeek等人工智能工具赋能家庭教育。报告从当前家长辅导时间与精力有限、能力不足及其引发的心理和人际关系困扰的实际背景出发,探讨了AI家庭教育的独特优势,并具体阐述了如何通过DeepSeek解决教育中的诸多痛点。报告不仅涵盖了AI辅助工具的基本功能介绍,还包括详细的分步骤实践指南。同时探讨了未来职业技能规划、AI伦理及其对孩子全面发展的重要性。此外,特别提到了如何在不同场景(如作业辅导、作文批改、情感疏导)中合理、高效使用DeepSeek,并展示了通过定制化学习路径培养创造力、数字素养和其他未来竞争所需的多项核心技能的成功案例。该报告不仅适合对AI应用于教育感兴趣的家长,还为希望了解前沿教育科技的研究者提供了有益的参考。 适用人群:希望借助人工智能改善子女教育质量和效率的家长;教育工作者,包括一线教师、培训机构教师;研究人员,尤其是致力于家庭教育技术和心理学领域研究的专业人士。 使用场景及目标:家长可通过本指南学习如何充分利用人工智能工具为孩子提供个性化的辅导和支持;教育从业者和研究人员可以借鉴

Global site tag (gtag.js) - Google Analytics