Leakcanary部分泄露警报无需修复

2024-06-10 12:08

本文主要是介绍Leakcanary部分泄露警报无需修复,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:

https://lynn8570.github.io/posts/some%20memory%20leaks%20that%20no%20need%20to%20be%20fixed/

前言

使用leakcanary检查内存泄露之后,由于他的工作原理,造成所有的在上下文关闭之后,还未被释放的资源就会引爆内存泄露通知。但是不是所有的泄露都需要修复的。下面总结几个我的血泪史,希望以后不要重蹈覆辙。

#InputMethodManager.sInstance泄露

输入法泄露,具体的泄露路径类似于

提示InputMethodManager.sInstance这个静态实例可能通过各种路径对context进行了泄露。具体的路径可能会不一样,但是归根到最后都是提示InputMethodManager.sInstance静态引用泄露。 通过网上搜索,可能有类似的修复,如下 public static final class TypedObject { private final Object object; private final Class type;

    public TypedObject(final Object object, final Class type){this.object = object;this.type = type;}Object getObject(){return object;}Class getType(){ return type;}
}public static void invokeMethodExceptionSafe(final Object methodOwner, final String method, final TypedObject... arguments)
{if (null == methodOwner){return;}try{final Class<?>[] types = null == arguments ? new Class[0] : new Class[arguments.length];final Object[] objects = null == arguments ? new Object[0] : new Object[arguments.length];if (null != arguments){for (int i = 0, limit = types.length; i < limit; i++){types[i] = arguments[i].getType();objects[i] = arguments[i].getObject();}}final Method declaredMethod = methodOwner.getClass().getDeclaredMethod(method, types);declaredMethod.setAccessible(true);declaredMethod.invoke(methodOwner, objects);}catch (final Throwable ignored){}
}public static void fixInputMethodManager(Activity activity)
{final Object imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE);final Reflector.TypedObject windowToken= new Reflector.TypedObject(activity.getWindow().getDecorView().getWindowToken(), IBinder.class);Reflector.invokeMethodExceptionSafe(imm, "windowDismissed", windowToken);final Reflector.TypedObject view= new Reflector.TypedObject(null, View.class);Reflector.invokeMethodExceptionSafe(imm, "startGettingWindowFocus", view);
}

主要通过反射,修复内存泄露。

但是,下面的话,非常重要,非常重要,非常重要,重要的事情说三遍:这个属于系统级别的泄露,也就是说,你不泄露,别人也会泄露,而且整个android系统,只保留一个static instance的引用,所以这个修复,对整个系统的内存没有太大的改善。而且这个修复的隐患是,你有可能会在页面跳转的时候,遇到各种不可预测的编辑框无法获取焦点的问题。所以,我建议,这个泄露,可以忽略。

AsyncQueryHandler 没有quit

有时候我们会遇到HandlerThread没有quit而爆出的泄露,泄露路径如下:

而android系统中有个AsyncQueryWorker从源代码看

public AsyncQueryHandler(ContentResolver cr) {super();mResolver = new WeakReference<ContentResolver>(cr);synchronized (AsyncQueryHandler.class) {if (sLooper == null) {HandlerThread thread = new HandlerThread    ("AsyncQueryWorker");thread.start();sLooper = thread.getLooper();}}mWorkerThreadHandler = createHandler(sLooper);
}

这个名为AsyncQueryWorker的HandlerThread自从start之后就没人管了。这个时候,leakcanary也会提示泄露。 于是我曾自作聪明,通过反射将这个sLooper强制退出,代码如下:

//linlian@2015.06.01 release static sLooper in AsyncQueryHandler
public static void fixAsyncQueryWorker(){Field sLooperCached = null;try {sLooperCached = Class.forName("android.content.AsyncQueryHandler").getDeclaredField("sLooper");sLooperCached.setAccessible(true);} catch (Exception ex) {ex.printStackTrace();}if (sLooperCached == null) return;Looper looper = null;try {// Get reference to the sLooperCached looper = (Looper)sLooperCached.get(null);if(looper!=null){looper.quit();sLooperCached.set(null,null);}} catch (Exception ex) {ex.printStackTrace();}

这个修复的惨痛后果是,有些后台线程直接结束了,所以,对于AsyncQueryHandler的泄露,我也是建议不修复。

TextLine.sCached 泄露

和inputManager一样,这个泄露,属于系统的静态引用而造成的泄露,但是这个泄露的修复,目前没有发现什么不良的影响,但是泄露修复的价值意义不知道大不大,也是你不泄露,别人也会泄露,反正总有一个这样的引用存在的。修复的效果也不是很明显 修复代码如下

public static void clearTextLineCache(){Field textLineCached = null;try {textLineCached = Class.forName("android.text.TextLine").getDeclaredField("sCached");textLineCached.setAccessible(true);} catch (Exception ex) {ex.printStackTrace();}if (textLineCached == null) return;Object cached = null;try {// Get reference to the TextLine sCached array.cached = textLineCached.get(null);} catch (Exception ex) {ex.printStackTrace();}if (cached != null) {// Clear the array.for (int i = 0, size = Array.getLength(cached); i < size; i ++) {Array.set(cached, i, null);}}
}

总结

LeakCanary是一个很好检查内存泄露的工具,但不是所有的泄露都需要修复,有些事android系统的泄露bug,通过各种方式曲线救国之后,不一定会达到一个很好的内存改善结果,所以干脆不要去动他,以免引起不可预测的运行异常。只有自己非常肯定的,由于使用不规范等引起的内存泄露才是我们重点关注的部分

这篇关于Leakcanary部分泄露警报无需修复的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048122

相关文章

电脑找不到mfc90u.dll文件怎么办? 系统报错mfc90u.dll丢失修复的5种方案

《电脑找不到mfc90u.dll文件怎么办?系统报错mfc90u.dll丢失修复的5种方案》在我们日常使用电脑的过程中,可能会遇到一些软件或系统错误,其中之一就是mfc90u.dll丢失,那么,mf... 在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包

电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案

《电脑显示mfc100u.dll丢失怎么办?系统报错mfc90u.dll丢失5种修复方案》最近有不少兄弟反映,电脑突然弹出“mfc100u.dll已加载,但找不到入口点”的错误提示,导致一些程序无法正... 在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“找不到指定的模块”或“缺少某个DL

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

mss32.dll文件丢失怎么办? 电脑提示mss32.dll丢失的多种修复方法

《mss32.dll文件丢失怎么办?电脑提示mss32.dll丢失的多种修复方法》最近,很多电脑用户可能遇到了mss32.dll文件丢失的问题,导致一些应用程序无法正常启动,那么,如何修复这个问题呢... 在电脑常年累月的使用过程中,偶尔会遇到一些问题令人头疼。像是某个程序尝试运行时,系统突然弹出一个错误提

电脑提示找不到openal32.dll文件怎么办? openal32.dll丢失完美修复方法

《电脑提示找不到openal32.dll文件怎么办?openal32.dll丢失完美修复方法》openal32.dll是一种重要的系统文件,当它丢失时,会给我们的电脑带来很大的困扰,很多人都曾经遇到... 在使用电脑过程中,我们常常会遇到一些.dll文件丢失的问题,而openal32.dll的丢失是其中比较

电脑win32spl.dll文件丢失咋办? win32spl.dll丢失无法连接打印机修复技巧

《电脑win32spl.dll文件丢失咋办?win32spl.dll丢失无法连接打印机修复技巧》电脑突然提示win32spl.dll文件丢失,打印机死活连不上,今天就来给大家详细讲解一下这个问题的解... 不知道大家在使用电脑的时候是否遇到过关于win32spl.dll文件丢失的问题,win32spl.dl

电脑提示msvcp90.dll缺少怎么办? MSVCP90.dll文件丢失的修复方法

《电脑提示msvcp90.dll缺少怎么办?MSVCP90.dll文件丢失的修复方法》今天我想和大家分享的主题是关于在使用软件时遇到的一个问题——msvcp90.dll丢失,相信很多老师在使用电脑时... 在计算机使用过程中,可能会遇到 MSVCP90.dll 丢失的问题。MSVCP90.dll 是 Mic

电脑报错cxcore100.dll丢失怎么办? 多种免费修复缺失的cxcore100.dll文件的技巧

《电脑报错cxcore100.dll丢失怎么办?多种免费修复缺失的cxcore100.dll文件的技巧》你是否也遇到过“由于找不到cxcore100.dll,无法继续执行代码,重新安装程序可能会解... 当电脑报错“cxcore100.dll未找到”时,这通常意味着系统无法找到或加载这编程个必要的动态链接库