千家信息网

Android内存泄漏实例分析

发表于:2025-11-08 作者:千家信息网编辑
千家信息网最后更新 2025年11月08日,本文小编为大家详细介绍"Android内存泄漏实例分析",内容详细,步骤清晰,细节处理妥当,希望这篇"Android内存泄漏实例分析"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知
千家信息网最后更新 2025年11月08日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安全错误 数据库的锁怎样保障安全 工业网络技术比较强的公司 高端笔记本能当服务器吗 数据库保护包括数据的安全性 杀戮空间2进去服务器看不到角色 江苏常州服务器托管云空间 为什么服务器的时间需要同步 如何使用服务器收代码作业 信息系统 数据库 医院 数据库冲突怎样加锁 软件开发需要签保密协议 音视频开发和软件开发 预防公司网络安全员工怎么做 蓬莱区软件开发培训 网站服务器功能 得实e学显示服务器错误 32岁软件开发 郴州品易居互联网科技公司 华为x86服务器整体出售价格 我国网络安全事件损失 学习电脑软件开发要多久 亚洲第二大软件开发公司 华为武长地区通用软件开发 数据库和网络安全哪个好学 万有网络技术有限公司员工待遇 网络安全领导组的职责 哈利波特官方服务器怎么下载 我是网络安全守护者闯关 360安全程序代理服务器 大逃杀服务器维护 银行账户管理服务器
0