一种内存泄漏的检测方法和装置技术领域
本发明涉及计算机技术领域,尤其涉及一种内存泄漏的检测方法和装置。
背景技术
内存泄漏是指功能模块持续申请内存空间,当结束该功能后,该功能申请的内存
空间未能回收。内存泄漏的出现会导致内存不断上涨,最终引发系统强行结束应用,释放内
存。强行结束应用导致应用异常退出,降低用户体验。
在现有技术中,通过人工测试来检测内存泄漏。但是,人工测试偶然性,很难测试
出所有内存泄漏问题。并且,人工测试环境与实际应用环境存在差异,且人工测试在投入市
场前须完成,故人工测试很难还原内存泄漏的实际情况。
所以,由于现有技术依赖人工检测内存泄漏,所以导致检测内存泄漏和解决内存
泄漏周期长。
发明内容
发明实施例提供了一种内存泄漏的检测方法和装置,用于实现自动检测内存泄漏
的技术效果。
第一方面,本发明提供了一种内存泄漏的检测方法,包括:
内存检测模块对目标应用的每个作业Activity进行监控;
当监控到任一所述Activity退出,且所述Activity的一条或多条引用未被清除
时,确定所述目标应用存在内存泄漏;
将未被清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个二进
制转储文件hprof文件中,所述hprof文件能够表示出一条引用的引用关系;
基于每个所述hprof文件表示所述hprof文件存储的引用的引用关系,确定出每条
所述引用的引用链;
从一条或多条所述引用链中确定出导致内存泄漏的引用链。
可选的,基于每个所述hprof文件表示所述hprof文件存储的引用的引用关系,确
定出每条所述引用的引用链,包括:
解析每个所述hprof文件,获得每个所述hprof文件的引用键,所述hprof文件通过
所述引用键表示所述引用关系;
基于每个所述引用键,确定每个所述引用的直接引用函数;
计算每个所述直接引用函数到用于回收内存的垃圾回收函数的最短路径,所述最
短路径为所述引用链。
可选的,从一条或多条所述引用链中确定出导致内存泄漏的引用链,包括:
判断每个所述引用链的长度是否超过1;
当所述引用链的长度超过1时,确定所述引用链为所述导致内存泄漏的引用链。
可选的,在将未被清除的所述一条或多条引用一一倾卸到所述目标应用的一个或
多个二进制转储文件hprof文件中之前,还包括:
调用垃圾回收函数清除一个或多个所述引用;
当存在未能被所述垃圾回收函数清除的一个或多个所述引用时,执行所述将未被
清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个二进制转储文件hprof
文件中的步骤。
可选的,从一个或多个所述引用链中确定出导致内存泄漏的引用链之后,还包括:
将所述导致内存泄漏的引用链记录在报告文件中;
向与所述目标应用关联的服务器发送所述报告文件。
可选的,所述内存检测模块对应的代码插桩在所述目标应用的代码中,且所述内
存检测模块的代码与所述目标应用的代码在同一级目录下。
可选的,所述方法还包括:
所述目标应用在主线程中执行,所述内存检测模块在不同于主线程的内存检测线
程中执行。
第二方面,本发明提供了一种内存泄漏的检测装置,包括:
监控单元,用于对目标应用的每个作业Activity进行监控;
第一确定单元,用于当监控到任一所述Activity退出,且所述Activity的一条或
多条引用未被清除时,确定所述目标应用存在内存泄漏;
倾卸单元,用于将未被清除的所述一条或多条引用一一倾卸到所述目标应用的一
个或多个二进制转储文件hprof文件中,所述hprof文件能够表示出一条引用的引用关系;
第二确定单元,用于基于每个所述hprof文件表示所述hprof文件存储的引用的引
用关系,确定出每条所述引用的引用链;
第三确定单元,用于从一条或多条所述引用链中确定出导致内存泄漏的引用链。
可选的,所述第二确定单元用于解析每个所述hprof文件,获得每个所述hprof文
件的引用键,所述hprof文件通过所述引用键表示所述引用关系;基于每个所述引用键,确
定每个所述引用的直接引用函数;计算每个所述直接引用函数到用于回收内存的垃圾回收
函数的最短路径,所述最短路径为所述引用链。
可选的,所述第三确定单元用于判断每个所述引用链的长度是否超过1;当所述引
用链的长度超过1时,确定所述引用链为所述导致内存泄漏的引用链。
可选的,所述装置还包括:
筛选单元,用于在将未被清除的所述一条或多条引用一一倾卸到所述目标应用的
一个或多个二进制转储文件hprof文件中之前,调用垃圾回收函数清除一个或多个所述引
用;当存在未能被所述垃圾回收函数清除的一个或多个所述引用时,通知倾卸单元将未被
清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个二进制转储文件hprof
文件中的步骤。
可选的,所述装置还包括:
记录单元,用于从一个或多个所述引用链中确定出导致内存泄漏的引用链之后,
将所述导致内存泄漏的引用链记录在报告文件中;
发送单元,用于向与所述目标应用关联的服务器发送所述报告文件。
本申请实施例中的上述一个或多个技术方案,至少具有如下一种或多种技术效
果:
在本发明实施例的技术方案中,内存检测模块对目标应用的每个作业Activity进
行监控,当监控到任一Activity退出,且所述Activity的一条或多条引用未被清除时,确定
目标应用存在内存泄漏,然后将未被清除的一条或多条引用一一倾卸到目标应用的一个或
多个二进制转储文件hprof文件中,hprof文件能够表示出一条引用的引用关系,进而基于
每个hprof文件表示hprof文件存储的引用的引用关系,确定出每条引用的引用链,并从一
条或多条引用链中确定出导致内存泄漏的引用链。由上述描述看出,本发明实施例通过内
存检测模块实现了自动检测内存泄漏,并且根据hprof文件表示的引用关系确定出确定出
导致内存泄漏的引用链,实现了定位内存泄漏的所在位置。由此,解决了现有技术检测内存
泄漏依赖人工的技术问题,实现了自动检测并定位内存泄漏的技术效果。
附图说明
图1为本发明实施例中内存泄漏的检测方法流程图;
图2为本发明实施例中一示例性函数拓扑示意图;
图3为本发明实施例中内存泄漏的检测装置结构示意图。
具体实施方式
发明实施例提供了一种内存泄漏的检测方法和装置,用于实现自动检测内存泄漏
的技术效果。
为了解决上述技术问题,本发明提供的技术方案总体思路如下:
在本发明实施例的技术方案中,内存检测模块对目标应用的每个作业Activity进
行监控,当监控到任一Activity退出,且所述Activity的一条或多条引用未被清除时,确定
目标应用存在内存泄漏,然后将未被清除的一条或多条引用一一倾卸到目标应用的一个或
多个二进制转储文件hprof文件中,hprof文件能够表示出一条引用的引用关系,进而基于
每个hprof文件表示hprof文件存储的引用的引用关系,确定出每条引用的引用链,并从一
条或多条引用链中确定出导致内存泄漏的引用链。由上述描述看出,本发明实施例通过内
存检测模块实现了自动检测内存泄漏,并且根据hprof文件表示的引用关系确定出确定出
导致内存泄漏的引用链,实现了定位内存泄漏的所在位置。由此,解决了现有技术检测内存
泄漏依赖人工的技术问题,实现了自动检测并定位内存泄漏的技术效果。
下面通过附图以及具体实施例对本发明技术方案做详细的说明,应当理解本申请
实施例以及实施例中的具体特征是对本申请技术方案的详细的说明,而不是对本申请技术
方案的限定,在不冲突的情况下,本申请实施例以及实施例中的技术特征可以相互组合。
本文中术语“和/或”,仅仅是一种描述关联对象的关联关系,表示可以存在三种关
系,例如,A和/或B,可以表示:单独存在A,同时存在A和B,单独存在B这三种情况。另外,本文
中字符“/”,一般表示前后关联对象是一种“或”的关系。
本发明第一方面提供了一种内存泄漏的检测方法,请参考图1,为本发明实施例中
内存泄漏的检测方法流程图。该方法包括:
S101:内存检测模块对目标应用的每个作业Activity进行监控;
S102:当监控到任一所述Activity退出,且所述Activity的一条或多条引用未被
清除时,确定所述目标应用存在内存泄漏;
S103:将未被清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个
二进制转储文件hprof文件中,所述hprof文件能够表示出一条引用的引用关系;
S104:基于每个所述hprof文件表示所述hprof文件存储的引用的引用关系,确定
出每条所述引用的引用链;
S105:从一条或多条所述引用链中确定出导致内存泄漏的引用链。
具体来讲,为了便于在用户使用目标应用过程中对目标应用内存泄漏进行检测,
本发明实施例中的内存检测模块运行在目标应用中。具体来讲,在本发明实施例中,使用
Python语言编写内存检测模块的代码。Python是一种面向对象、解释型计算机程序设计语
言。Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,能够把用其
他语言制作的各种模块很轻松地联结在一起。编写好的内存检测模块代码再利用gradle或
ANT进行编译,最后插桩到目标应用的代码中。
其中,如果利用ANT的编译方式进行编译,则具体为将内存检测模块的代码编译打
包为canary.jar包,然后将canary.jar包插桩到目标应用的代码中。其中,canary.jar包是
爪哇JAVA语言搜集ANR(应用程序无响应,Application Not Responding)信息日志的工具
编译而成的。或者,如果利用gradle的编译方式进行编译,则无需打包,直接将内存检测模
块的代码插桩到目标应用的代码中即可。在具体实现过程中,本发明所属领域的普通技术
人员可以根据实际进行选择gradle、ANT或者其他编译方式,本发明不做具体限制。
进一步,为了避免内存检测模块对目标应用程序的正常运行产生影响,在本发明
实施例中,将内存检测模块的代码和目标应用程序的代码放置在同一级目录中。在运行目
标应用时,目标应用运行在主线程中,为用户提供目标应用的各个功能。而内存检测模块则
运行在不同于主线程的内存检测线程中,进而使得内存检测线程中执行的各个操作不会影
响主线程,进而不影响目标应用的正常运行。
上述对目标应用的改进完成后,与目标应用关联的服务器将改进后的目标应用发
送到各个应用下载平台或UE(用户设备,User Equipment)。进而UE从应用下载平台或者服
务器中下载目标应用,并将目标应用安装到UE中。由于目标应用中插桩了内存检测模块,因
此目标应用在UE中运行时,目标应用就可以自动对目标应用的内存泄漏进行检测和定位。
下面就对如何对内存泄漏检测和定位进行具体介绍。
首先,S101中,在目标应用运行过程中,内存检测模块也会随目标应用的运行而运
行,进而对目标应用的每个作业Activity进行监控。具体来讲,本发明实施例中的内存检测
模块具有引用链监控方法RefWatcher.watch()方法。利用RefWatcher.watch()方法在每
个Activity中创建能够监控Activity的弱引用键值KeyedWeakReference对象,进而
Activity在初始化Oncreat函数中初始化时,KeyedWeakReference对象也同时被初始化。
在正常情况下,Activity退出后,该Activity的全部引用将会被回收清除,进而释
放该Activity申请的内存。因此,当KeyedWeakReference监测到Activity退出,然而该
Activity的一条或多条引用却未被全部清除时,则S102中确定目标应用出现了内存泄漏。
为了定位导致内存泄漏的原因,进一步,在S103中,将未被清除的一条或多个引用
倾卸到目标应用的系统文件中的hprof文件中。具体为一条引用倾卸到一个hprof文件中。
换言之,一个Activity的hprof文件的数量,为该Activity未被清除的引用数量。二进制转
储文件hprof文件是一种快照存储类型的文件,它包含了所有数据表现方式,以及JAVA对象
和线程内部的基本数据类型,记录对象中域的值和hprof文件生成时有哪些方法在被执行。
正是由于hprof文件的特性,使得hprof文件能够表示引用的引用关系。
所以,S104中,基于每个hprof文件,确定出每条引用的引用链。在本发明实施例
中,S104通过如下过程实现:
解析每个所述hprof文件,获得每个所述hprof文件的引用键,所述hprof文件通过
所述引用键表示所述引用关系;
基于每个所述引用键,确定每个所述引用的直接引用函数;
计算每个所述直接引用函数到用于回收内存的垃圾回收函数的最短路径,所述最
短路径为所述引用链。
首先对hprof文件进行解析,解析出hprof文件中唯一的引用键reference key。其
中,hprof文件正是通过reference key来表示引用关系,通过reference key可以指示出这
条引用的直接引用函数。在本发明实施例中,直接引用函数指的是直接引用Activity的函
数。举例来说,函数A通过引用函数B进而引用函数C,而函数C引用了Activity,则函数C就是
Activity的直接引用函数。因此,基于每个引用键可以确定出每条引用的直接引用函数。
接下来,计算直接引用函数到GC(垃圾回收,Gabage,collection)函数的最短路
径。GC函数是用于在Activity退出后回收该Activity的各条引用的函数。引用不能被GC函
数回收,表示引用所在的引用链异常,引发内存泄漏。其中,本发明实施例中直接引用函数
到GC函数之间的最短路径就是引用链。
具体来讲,由于目标应用中存在大量的函数,且大部分函数可以引用其他函数,以
及被其他函数引用,所以,直接引用函数到GC函数的路径就有多条。举例来说,图2示出一函
数拓扑示意图。在图2中,直接引用函数为A函数,A函数到GC函数可以有两条路径,第一条为
“A函数-B函数-C函数-GC函数”,第二条为“A函数-D函数-GC函数”。由于第一条路径引用了
三次才到达GC函数,而第二条路径仅引用两次就到达GC函数,所以第二条路径最短,所以第
二条路径是A函数的引用链。通过类似的方式,获得每条引用的引用链,进而总共获得一条
或多条引用链。
确定出引用链之后,执行S105,从一条或多条引用链中确定出存在内存泄漏的引
用链。具体来讲,本发明实施例中的S105通过如下过程实现:
判断每个所述引用链的长度是否超过1;
当所述引用链的长度超过1时,确定所述引用链为所述导致内存泄漏的引用链。
具体来讲,判断引用链的长度是否超过1,进而判断引用链是否导致了内存泄漏。
在本发明实施例中,引用链的长度指的是直接引用函数到GC函数总共引用函数的次数。举
例来说,图2中的第一条路径的长度为3,第二条路径的长度为2。
当引用链长度超过1时,表示直接引用函数不能被GC函数所直接引用,进而表示直
接引用函数无法被GC函数直接清除,因此该引用链导致了内存泄漏。所以,在本发明实施例
中,将长度超过1的引用链作为引用内存泄漏的引用链。
进一步,为了能够更好地维护目标应用,作为一种可选的实施例,在S105之后,还
可以包括:
将所述导致内存泄漏的引用链记录在报告文件中;
向与所述目标应用关联的服务器发送所述报告文件。
具体来讲,将导致内存泄漏的引用链保存在UE中的报告文件中,并且将报告文件
发送给目标应用关联的服务器。由此使得服务器的管理人员通过查看报告文件中的一条或
多个引用链,进而还原出内存泄漏的情况,从而修复内存泄漏的问题。
或者,为了提示用户目标应用出现内存泄漏,作为一种可选的实施例,在S105之
后,还可以输出表示内存泄漏的提示信息。具体来讲,提示信息以及输出提示信息的方式有
多种。例如可以将导致内存泄漏的引用链传入为显示泄漏服务DisplayLeakService函数,
进而以通知栏显示通知的形式输出文字提示信息。或者,也可以调用音频输出函数输出异
常提示音。本发明所属领域的普通技术人员可以根据实际选择,本发明不做具体限制。
较佳地,作为一种可选的实施例,在将未被清除的一条或多条引用一一倾卸到
hprof文件中之前,还可以包括:
调用垃圾回收函数清除一个或多个所述引用;
当存在未能被所述垃圾回收函数清除的一个或多个所述引用时,执行所述将未被
清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个二进制转储文件hprof
文件中的步骤。
具体来讲,在具体实现过程中,Activity退出后,不能被清除的引用也可以并不是
由于内存泄漏而导致不能被清除,因此,为了筛选出是由于内存泄漏而不能清除的引用,同
时降低后续定位内存泄漏的计算量,在Activity退出后,内存检测线程如果检测到
Activity的引用没有被全部清除,则调用GC函数对这些未能被清除的引用再次尝试清除。
此时,对于并非内存泄漏导致不能被清除的引用将顺利被内存检测线程创建的GC
函数清除,而此时依然未能被GC函数清除的一条或多条引用,则就是由于内存泄漏而导致
不能清除的引用了。所以,通过上述过程就筛选出了真正定位内存泄漏需要的引用,同时也
降低了后续处理的数据量。
基于与前述实施例中内存泄漏的检测方法同样的发明构思,本发明第二方面还提
供一种内存泄漏的检测装置,如图3所示,包括:
监控单元101,用于对目标应用的每个作业Activity进行监控;
第一确定单元102,用于当监控到任一所述Activity退出,且所述Activity的一条
或多条引用未被清除时,确定所述目标应用存在内存泄漏;
倾卸单元103,用于将未被清除的所述一条或多条引用一一倾卸到所述目标应用
的一个或多个二进制转储文件hprof文件中,所述hprof文件能够表示出一条引用的引用关
系;
第二确定单元104,用于基于每个所述hprof文件表示所述hprof文件存储的引用
的引用关系,确定出每条所述引用的引用链;
第三确定单元105,用于从一条或多条所述引用链中确定出导致内存泄漏的引用
链。
具体来讲,第二确定单元104用于解析每个所述hprof文件,获得每个所述hprof文
件的引用键,所述hprof文件通过所述引用键表示所述引用关系;基于每个所述引用键,确
定每个所述引用的直接引用函数;计算每个所述直接引用函数到用于回收内存的垃圾回收
函数的最短路径,所述最短路径为所述引用链。
具体来讲,第三确定单元105用于判断每个所述引用链的长度是否超过1;当所述
引用链的长度超过1时,确定所述引用链为所述导致内存泄漏的引用链。
进一步,本发明实施例中的内存泄漏的检测装置还可以包括:
筛选单元,用于在将未被清除的所述一条或多条引用一一倾卸到所述目标应用的
一个或多个二进制转储文件hprof文件中之前,调用垃圾回收函数清除一个或多个所述引
用;当存在未能被所述垃圾回收函数清除的一个或多个所述引用时,通知倾卸单元将未被
清除的所述一条或多条引用一一倾卸到所述目标应用的一个或多个二进制转储文件hprof
文件中的步骤。
更进一步,本发明实施例中的内存泄漏的检测装置还可以包括:
记录单元,用于从一个或多个所述引用链中确定出导致内存泄漏的引用链之后,
将所述导致内存泄漏的引用链记录在报告文件中;
发送单元,用于向与所述目标应用关联的服务器发送所述报告文件。
前述图1-图2实施例中的内存泄漏的检测方法的各种变化方式和具体实例同样适
用于本实施例的内存泄漏的检测装置,通过前述对内存泄漏的检测方法的详细描述,本领
域技术人员可以清楚的知道本实施例中内存泄漏的检测装置的实施方法,所以为了说明书
的简洁,在此不再详述。
本申请实施例中的上述一个或多个技术方案,至少具有如下一种或多种技术效
果:
在本发明实施例的技术方案中,内存检测模块对目标应用的每个作业Activity进
行监控,当监控到任一Activity退出,且所述Activity的一条或多条引用未被清除时,确定
目标应用存在内存泄漏,然后将未被清除的一条或多条引用一一倾卸到目标应用的一个或
多个二进制转储文件hprof文件中,hprof文件能够表示出一条引用的引用关系,进而基于
每个hprof文件表示hprof文件存储的引用的引用关系,确定出每条引用的引用链,并从一
条或多条引用链中确定出导致内存泄漏的引用链。由上述描述看出,本发明实施例通过内
存检测模块实现了自动检测内存泄漏,并且根据hprof文件表示的引用关系确定出确定出
导致内存泄漏的引用链,实现了定位内存泄漏的所在位置。由此,解决了现有技术检测内存
泄漏依赖人工的技术问题,实现了自动检测并定位内存泄漏的技术效果。
本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序
产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实
施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机
可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产
品的形式。
本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程
图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流
程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序
指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产
生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实
现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特
定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指
令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或
多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计
算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或
其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一
个方框或多个方框中指定的功能的步骤。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精
神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围
之内,则本发明也意图包含这些改动和变型在内。