千家信息网

Android内存泄漏实例分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本文小编为大家详细介绍"Android内存泄漏实例分析",内容详细,步骤清晰,细节处理妥当,希望这篇"Android内存泄漏实例分析"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知
千家信息网最后更新 2026年11月01日Android内存泄漏实例分析

本文小编为大家详细介绍"Android内存泄漏实例分析",内容详细,步骤清晰,细节处理妥当,希望这篇"Android内存泄漏实例分析"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

在这次开发过程中,需要用到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 buffer_local(env, env->NewByteArray(out->capacity())); +            m_buffer = static_cast(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.

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

读到这里,这篇"Android内存泄漏实例分析"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。

方法 内存 时候 问题 办法 就是 进程 实例 实例分析 分析 对内 文章 是在 界面 系统 页面 应用 不好 内容 出处 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 中国互联网科技工作委员会毛军 互联网科技有限公司图片 互联网最新的科技有限公司 有马互联网科技 狮子座互联网科技有限公司 广州凡科互联网科技 融贸通互联网科技 兼蜜互联网科技 一五八零互联网科技 玖二柒互联网科技公司待遇 互联网科技有哪些公司 受益于互联网科技的高速发展 赶超互联网科技 微信多开 辽宁互联网新科技 徐州市互联网科技有限公司 互联网科技企业商标注意事项 互联网时代高科技布局 河南商务圈互联网科技有限公司 前海云享互联网科技 互联网科技深圳 金融科技与互联网金融相同和不同 乌鲁木齐新华智原互联网科技学校 互联网行业科技股 互联网科技公司营业执照怎么办理 广州富喜互联网络科技 广州智享互联网科技 华人运通互联网科技公司 现代科技的标志之一的互联网 科技发展第三阶段互联网时代
0