一种内存泄露检测方法及设备与流程

文档序号:15685992发布日期:2018-10-16 21:03阅读:114来源:国知局
本发明涉及计算机领域,尤其涉及一种内存泄露检测方法及设备。
背景技术
:在计算机领域中,内存泄露指由于疏忽或错误造成程序已经不再使用的内存无法被回收。随着应用程序的运行,系统中可用的内存越来越少,导致系统由于没有足够的内存而瘫痪。目前,检测内存泄漏的手段是内存分析工具。内存分析工具首先通过对应用程序运行时导出的文件人为地判断对象实例数量、或对象内存占用大小来找到有高风险内存泄露的类;然后再在另一个时间导出一个文件进行同样的分析,对比两次分析结果,如果发现某个类的实例数量有明显增加、且大致趋势是随着应用程序的运行一直增加,那么所述类即可为内存泄露的重点关注对象;最后再人为参与进行更深度地分析以确定内存泄露的对象。但是,实践中发现,上述整个内存泄露的检测过程需要人为的参与,且需要对内存泄露场景比较熟悉的人员进行检测,内存泄露检测的效率较低。技术实现要素:本发明实施例公开了一种内存泄露检测方法及设备,能够提高内存泄露检测的效率。第一方面,本发明实施例提供了一种内存泄露检测方法,所述方法包括:当应用程序在虚拟机上运行时,调用java虚拟机工具接口jvmti监控是否存在对象被回收;其中所述对象关联有标示符;在监控到存在所述对象被回收的情况下,在预设集合中删除所述对象关联的标示符;其中所述预设集合包括多个对象各自关联的标示符;其中,所述预设集合中剩余的标示符可以用于确定内存泄露对象。具体的,内存泄露检测设备确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象。本发明实施例中,内存泄露检测设备借助所述jvmti能够监控应用程序中对象是否被回收的能力,检测出所述应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本方案减少了人力资源的消耗,提高了内存泄露检测的效率。在一种可能的设计中,通过代码注入技术跟踪所述对象的创建事件从而获取所述对象的位置信息。其中,所述获取的对象的位置信息可以用于确定所述内存泄露对象的位置。具体的,内存泄露检测设备根据所述位置信息确定所述内存泄露对象的位置。通过本发明实施例提供的技术方案,所述内存泄露检测设备在确定内存泄露对象的同时,还可以定位所述内存泄露对象的位置,避免了人为地去寻找所述内存泄露对象的位置,提高了内存泄露检测的效率。在一种可能的设计中,通过所述jvmti的thread-local机制创建所述对象所在线程的分配列表;以及调用信息传递接口函数将所述对象的标示符和位置信息传递给所述分配列表中;其中,所述线程各自关联一个分配列表;所述分配列表包括多个对象各自关联的标示符和位置信息;以及所述分配列表中同一个对象的标示符和位置信息具有关联关系;所述根据所述位置信息确定所述内存泄露对象的位置,包括:根据所述分配列表中的位置信息确定所述内存泄露对象的位置。通过本发明实施提供的技术方案,通过所述jvmti的thread-local机制创建的所述分配列表来保存所述标示符和所述位置信息,避免了多线程并发问题。在一种可能的设计中,所述根据所述分配列表中的位置信息确定所述内存泄露对象的位置,包括:调用在所述jvmti中已创建的守护线程导出所述分配列表中的标示符和位置信息。其中,该导出的所述标示符和所述位置信息可以用于确定所述内存泄露对象的位置。具体的,内存泄露检测设备可以根据导出的所述标示符和所述位置信息确定所述内存泄露对象的位置。通过本发明实施例提供的技术方案,所述内存泄露检测设备还可以通过创建的守护线程不定时地导出所述位置信息,避免了因所述位置信息都存在于内存中,而导致内存的使用率过高。在一种可能的设计中,获取包括指定目录的启动指令;其中所述启动指令用于启动文件检测线程,所述启动文件检测线程用于检测所述指定目录下是否存在开始文件或结束文件,所述开始文件用于触发启动监控对象的回收情况,所述结束文件用于触发结束监控对象的回收情况;当检测到所述指定目录下存在所述开始文件时,触发执行所述调用jvmti监控是否存在对象被回收的步骤;当检测到所述指定目录下存在所述结束文件时,结束对所述对象的回收情况的监控,并触发执行所述确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象的步骤。通过本发明实施例提供的技术方案,所述jvmti可以只监控在检测到所述开始文件之后创建的对象,避免监控应用程序中所有的对象,监控的对象的数量级小,内存泄露检测效率高;另外,在所述应用程序运行过程中,所述内存泄露检测设备还可以不定时地启动文件检测线程,以实现在所述应用程序运行的任一时间点开始监控对象的回收情况,从而实现监控范围的灵活设置。在一种可能的设计中,调用在所述jvmti中已创建的守护线程导出所述预设集合中剩余的标示符;根据导出的所述标示符确定内存泄露对象。通过本发明实施例提供的技术方案,所述内存泄露检测设备通过所述jvmti创建守护线程,来专门导出所述剩余的标示符,避免了因通过所述应用程序中的业务线程执行上述导出操作而影响所述应用程序的运行效率。在一种可能的设计中,根据所述预设集合中剩余的标示符和预设的排除对象确定内存泄露对象。通过本发明实施例提供的方案,所述内存泄露检测设备还可以预先设定排除对象,比如与应用程序具有相同的生命周期、且被正常引用的静态对象或全局对象等等,在确定所述内存泄露对象时,排除所述排除对象,避免了所述静态对象或全局对象等设定的所述排除对象被误定义为所述内存泄露对象,提高了内存泄露对象检测的准确率。在一种可能的设计中,所述根据导出的所述标示符和所述位置信息确定所述内存泄露对象的位置之后,所述方法还包括:在所述内存泄露对象的位置信息出现重复的情况下,去掉所述内存泄露对象的位置信息中重复的位置信息通过本发明实施例提供的技术方案,在导出的所述位置信息出现重复的情况下,所述内存泄露检测设备通过对所述内存泄露对象的位置信息进行去重操作,可以使所述内存泄露对象的位置信息直观上简洁、明了。第二方面,本发明实施例提供一种内存泄露检测设备,所述设备包括:监控单元,用于当应用程序在虚拟机上运行时,调用java虚拟机工具接口jvmti监控是否存在对象被回收;其中所述对象关联有标示符;标示符删除单元,用于在所述监控单元监控到存在所述对象被回收的情况下,在预设集合中删除所述对象关联的标示符;其中所述预设集合包括多个对象各自关联的标示符;对象确定单元,用于确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象。本发明实施例中,内存泄露检测设备监控出应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本发明实施例提供的方案减少了人力资源的消耗,提高了内存泄露检测的效率。在一种可能的设计中,所述设备还包括:位置确定单元,用于通过代码注入技术跟踪所述对象的创建事件从而获取所述对象的位置信息;并根据所述位置信息确定所述内存泄露对象的位置。通过本发明实施例提供的技术方案,所述内存泄露检测设备在确定内存泄露对象的同时还可以定位所述内存泄露对象的位置,避免了人为地去寻找所述内存泄露对象的位置,提高了内存泄露检测的效率。在一种可能的设计中,所述位置确定单元,具体用于通过所述jvmti的thread-local机制创建所述对象所在线程的分配列表;以及调用信息传递接口函数将所述对象的标示符和位置信息传递给所述分配列表;其中,所述线程各自关联一个分配列表;所述分配列表包括多个对象各自关联的标示符和位置信息;所述分配列表中同一个对象的标示符和位置信息具有关联关系;根据所述分配列表中的位置信息确定所述内存泄露对象的位置。通过本发明实施提供的技术方案,通过所述jvmti的thread-local机制创建的所述分配列表来保存所述标示符和所述位置信息,避免了多线程并发问题。在一种可能的设计中,所述位置确定单元,具体用于调用在所述jvmti中已创建的守护线程导出所述分配列表中的标示符和位置信息;以及根据导出的所述标示符和所述位置信息确定所述内存泄露对象的位置。通过本发明实施例提供的技术方案,所述内存泄露检测设备还可以通过创建的守护线程不定时地导出所述位置信息,避免了因所述位置信息都存在于内存中,而导致内存的使用率过高。在一种可能的设计中,所述设备还包括:获取单元,用于获取包括指定目录的启动指令;其中所述启动指令用于启动文件检测线程,所述文件检测线程用于检测所述指定目录下是否存在开始文件或结束文件,所述开始文件用于触发启动监控对象的回收情况,所述结束文件用于触发结束监控对象的回收情况;当检测到所述指定目录下存在所述开始文件时,触发执行所述调用jvmti监控是否存在对象被回收的步骤;当检测到所述指定目录下存在所述结束文件时,结束对所述对象的回收情况的监控,并触发执行所述确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象的步骤。通过本发明实施例提供的技术方案,所述jvmti可以只监控在检测到所述开始文件之后创建的对象,避免监控应用程序中所有的对象,监控的对象的数量级小,内存泄露检测效率高;另外,在所述应用程序运行过程中,所述内存泄露检测设备还可以不定时地启动文件检测线程,以实现在所述应用程序运行的任一时间点开始监控对象的回收情况,从而实现监控范围的灵活设置。在一种可能的设计中,所述对象确定单元,具体用于调用在所述jvmti中已创建的守护线程导出所述预设集合中剩余的标示符;以及根据导出的所述标示符确定内存泄露对象。通过本发明实施例提供的技术方案,所述内存泄露检测设备通过所述jvmti创建守护线程,来专门导出所述剩余的标示符,避免了因通过所述应用程序中的业务线程执行上述导出操作而影响所述应用程序的运行效率。在一种可能的设计中,所述对象确定单元,具体用于根据所述预设集合中剩余的标示符和预设的排除对象确定内存泄露对象。与现有技术相比,本发明实施例的有益效果:本发明实施例中,内存泄露检测设备借助所述jvmti能够监控应用程序中对象是否被回收的能力,检测出所述应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本方案减少了人力资源的消耗,提高了内存泄露检测的效率。附图说明为了更清楚地说明本发明实施例中的技术方案,下面将对实施例中所需要使用的附图作简单地介绍。图1是本发明实施例公开的一种jvmti的架构模型示意图;图2是本发明实施例公开的一种内存泄露检测方法的流程示意图;图3是本发明实施例公开的一种内存泄露检测设备的结构示意图;图4是本发明实施例公开的另一种内存泄露检测设备的结构示意图;图5是本发明实施例公开的另一种内存泄露检测设备的结构示意图;图6是本发明实施例公开的另一种内存泄露检测设备的结构示意图。具体实施方式下面将结合附图,对本发明的实施例进行描述。请参见图1,图1为本发明实施例公开的一种java虚拟机工具接口(javavirtualmachinetoolinterface,jvmti)的架构模型示意图。jvmti是一个基于c的应用程序编程接口(applicationprogramminginterface,api),通过所述jvmti的函数可以监控应用程序等,其架构模型可以如图1所示。所述jvmti可以向运行中的应用程序订阅感兴趣的事件,比如对象的回收、线程的结束等,当订阅的事件发生时,可以以回调函数的方式激活所述jvmti,并通过所述jvmti提供的功能函数对所述事件进行处理。需要说明的是,本发明实施例包括但不限于java语言,比如还可包括其他自动化内存管理的编程语言等。请参见图2,图2为本发明实施例公开的一种内存泄露检测方法的流程示意图。如图2所示,所述内存泄露检测方法可以包括以下步骤。步骤s201:当应用程序在虚拟机上运行时,调用java虚拟机工具接口jvmti监控是否存在对象被回收;其中所述对象关联有标示符。内存泄露检测设备可以先调用对象处理函数为所述应用程序的对象分配标示符,然后通过信息传递接口函数将所述标示符传递给所述jvmti;或者,所述内存泄露检测设备还可以直接调用所述jvmti中的函数为所述对象分配标示符等。在所述jvmti中,所述内存泄露检测设备可以调用所述jvmti中的settag()函数将所述标示符和所述对象关联起来,所述标示符和所述对象关联之后,通过所述标示符即可识别关联的所述对象。其中所述标示符可以用字母、数字或符号等表示,比如tag_01、tag_02和tag_03等;另外为了避免多线程并发问题,所述标示符还可以具有原子操作特性;所述信息传递接口函数可以包括java本地接口(javanativeinterface,jni)函数等跨平台接口函数。举例说明,若所述jvmti中的函数分别为对象object_01~object_05分配标示符tag_01~tag_05,即对象object_01被分配的标示符为tag_01、对象object_02被分配的标示符为tag_02、对象object_03被分配的标示符为tag_03、对象object_04被分配的标示符为tag_04和对象object_05被分配的标示符为tag_05;且所述settag()的函数原型为jvmtierrorsettag(jobjectobject,jlongtag),第一个参数是对象object,第二个参数是对象object被分配的标示符tag,通过jvmtierrorsettag(jobjectobject,jlongtag)函数可以将对象object和标示符tag关联起来。因此,所述内存泄露检测设备可以调用下面各个函数分别将对象object_01~object_05和标示符tag_01~tag_05一一关联起来。jvmtierrorsettag(jobjectobject_01,jlongtag_01);jvmtierrorsettag(jobjectobject_02,jlongtag_02);jvmtierrorsettag(jobjectobject_03,jlongtag_03);jvmtierrorsettag(jobjectobject_04,jlongtag_04);jvmtierrorsettag(jobjectobject_05,jlongtag_05);对象object_01~object_05和标示符tag_01~tag_05关联起来之后,在对象object_01~object_05中,通过tag_01即可识别出关联的对象object_01,通过tag_02即可识别出关联的对象object_02,通过tag_03即可识别出关联的对象object_03,通过tag_04即可识别出关联的对象object_04,通过tag_05即可识别出关联的对象object_05。本发明实施例中,所述内存泄露检测设备还可以调用所述jvmti中的函数建立预设集合,用来存储所述对象关联有标示符。比如,所述jvmti建立如表1所示的预设集合,用于存储标示符tag_01~tag_05。表1预设集合tag_01tag_02tag_03tag_04tag_05本发明实施例中,所述内存泄露检测设备可以调用所述jvmti中的回调函数检测是否存在对象被回收。进一步地,所述回调函数可以为objectfree(),所述objectfree()的函数原型为voidjnicallobjectfree(jvmtienv*jvmti_env,jlongtag),第二个参数是被回收对象关联的标示符,即当所述回调函数为voidjnicallobjectfree(jvmtienv*jvmti_env,jlongtag)时,则表明标示符tag关联的对象被回收。举例说明,若所述jvmti的回调函数为voidjnicallobjectfree(jvmtienv*jvmti_env,jlongtag_01)时,则表明标示符tag_01关联的对象object_01被回收,若当若所述jvmti的回调函数为voidjnicallobjectfree(jvmtienv*jvmti_env,jlongtag_02)时,则表明标示符tag_02关联的对象object_02被回收等。步骤s202:在监控到存在所述对象被回收的情况下,在预设集合中删除所述对象关联的标示符;所述内存泄露检测设备可以调用所述jvmti中的函数在预设集合中删除所述对象关联的标示符。比如,若所述预设集合如表1所示,所述jvmti监控到对象object_01和object_02被回收,则如表2所示,所述内存泄露检测设备可以调用所述jvmti中的函数从表1中删除对象object_01和object_02关联的标示符tag_01和tag_02。表2预设集合tag_03tag_04tag_05步骤s203:确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象。所述内存泄露检测设备可以调用所述jvmti创建的守护线程导出所述剩余的标示符到分析程序中进行分析,以确定内存泄露对象。进一步地,所述内存泄露检测设备还可以在所述jvmti检测到所述应用程序的垃圾回收结束的情况下,调用所述jvmti创建的守护线程导出所述剩余的标示符到分析程序中进行分析,以确定内存泄露对象。其中,所述jvmti可以通过回调函数检测所述应用程序的垃圾回收结束,比如,通过所述jvmti的回调函数garbagecollectionfinish()检测所述应用程序的垃圾回收结束。在一种可选的实施方式中,所述内存泄露检测设备可以将所述剩余的标示符关联的对象定义为所述内存泄露对象。比如,若如表2所示,所述剩余的标示符为tag_03、tag_04和tag_05,则所述内存泄露检测设备可以将tag_03、tag_04和tag_05关联的对象object_03、object_04和object_05定义为内存泄露对象。在另一种可选的实施方式中,所述内存泄露检测设备可以预先设定排除对象,所述排除对象可以包括与所述应用程序具有相同的生命周期、且被正常引用的静态对象或全局对象、或缓存中的对象、或容器中的对象等等。进一步地,所述内存泄露检测设备可以先确定所述剩余的标示符关联的对象,然后再从确定的所述对象中排除所述排除对象,最后将排除完后剩余的对象作为所述内存泄露对象。比如,若所述排除对象为object_03,所述剩余的标示符为tag_03、tag_04和tag_05,所述内存泄露检测设备可以先确定tag_03、tag_04和tag_05关联的对象为object_03、object_04和object_05,然后再从object_03、object_04和object_05中排除对象object_03,最后将排除完后剩余的对象object_04和object_05定义为内存泄露对象。或者,所述内存泄露检测设备还可以先查找所述排除对象关联的标示符,然后从所述剩余的标示符中排除所述排除对象关联的标示符,最后确定排除完所述排除对象关联的标示符之后所剩余的标示符,并将确定的所述标示符关联的对象定义为所述内存泄露对象。比如,若所述排除对象关联的标示符为tag_03,所述剩余的标示符为tag_03、tag_04和tag_05,所述内存泄露检测设备可以先从tag_03、tag_04和tag_05中排除tag_03,然后将tag_04和tag_05关联的对象object_04和object_05定义为内存泄露对象。通过本发明实施例提供的方案,所述内存泄露检测设备还可以预先设定排除对象,比如与应用程序具有相同的生命周期、且被正常引用的静态对象或全局对象等等,在确定所述内存泄露对象时,排除所述排除对象,避免了所述静态对象或全局对象等设定的所述排除对象被误定义为所述内存泄露对象,提高了内存泄露对象检测的准确率。另外,所述内存泄露检测设备通过所述jvmti创建守护线程,来专门导出所述剩余的标示符,避免了因通过所述应用程序中的业务线程执行上述导出操作而影响所述应用程序的运行效率。本发明实施例中,所述内存泄露检测设备借助所述jvmti能够监控应用程序中对象是否被回收的能力,检测出所述应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本发明实施例提供的方案减少了人力资源的消耗,提高了内存泄露检测的效率。在一种可选的实施例中,所述内存泄露检测设备可以设定监控范围,并检测所述监控范围内创建的对象中是否存在内存泄露对象。其中所述内存泄露检测设备可以通过步骤1)~步骤3)来设定所述监控范围。步骤1)、获取包括指定目录的启动指令;其中所述启动指令可以用于启动文件检测线程,所述文件检测线程用于检测所述指定目录下是否存在开始文件或结束文件,其中所述开始文件用于触发启动监控对象的回收情况,所述结束文件用于触发结束监控对象的回收情况;步骤2)、当检测到所述指定目录下存在所述开始文件时,触发执行所述调用jvmti监控是否存在对象被回收的步骤;步骤3)、当检测到所述指定目录下存在所述结束文件时,结束对所述对象的回收情况的监控,并触发执行所述根据所述预设集合中剩余的标示符确定内存泄露对象的步骤。所述开始文件或结束文件可以作为进程间通信手段,实现了统计开始进程/结束进程与被监控进程的交互。具体的,所述内存泄露检测设备可以预先通过代码注入技术在所述应用程序中注入文件检测线程。在所述应用程序运行过程中,所述内存泄露检测设备可以通过获取的所述启动指令来启动所述文件检测线程,所述文件检测线程检测所述启动指令指示的指定目录下是否存在所述开始文件或结束文件,若存在所述开始文件,则所述开始文件触发统计开始进程执行调用jvmti监控是否存在对象被回收的步骤,若存在所述结束文件,则所述结束文件触发统计结束进程执行所述根据所述预设集合中剩余的标示符确定内存泄露对象的步骤。其中所述启动指令可以是通过定时器或其他外部应用程序向所述内存泄露检测设备发送的。举例说明,在所述应用程序运行过程中,若时刻1定时器向所述内存泄露检测设备发送第一启动指令,来启动所述文件检测线程检测第一指定目录下是否存在所述开始文件,若存在所述开始文件,则所述开始文件触发统计开始进程执行调用jvmti监控是否存在对象被回收的步骤;若时刻2定时器向所述内存泄露检测设备发送第二启动指令,来启动所述文件检测线程检测第二指定目录下是否存在所述结束文件,若存在所述结束文件,则所述结束文件触发统计结束进程执行所述根据所述预设集合中剩余的标示符确定内存泄露对象的步骤。其中,所述指定目录可以windows,linux和solaris等操作系统下存在的目录。进一步地,若检测第一指定目录下存在到所述开始文件时,所述统计开始进程可以在所述应用程序当前运行的位置处部署开始标识,并调用所述jvmti监控所述开始标识之后创建的对象;若检测第二指定目录下存在所述结束文件时,所述统计结束进程可以在所述应用程序当前运行的位置处部署结束标识,并结束对所述对象的回收情况的监控。举例说明,所述应用程序的代码片段如下:进程1{对象a;对象b;};进程2{对象c;};如下所示,若所述文件检测线程在时刻1检测到所述开始文件,则所述统计开始进程可以在时刻1所述应用程序的运行位置(进程1的入口函数处)部署开始标识,并调用所述jvmti监控所述开始标识之后创建的对象;若所述文件检测线程在时刻2检测到所述结束文件,则所述统计结束进程可以在时刻2所述应用程序的运行位置(进程1的结束位置)处部署结束标识,并结束对所述对象的回收情况的监控。开始标识;进程1{对象a;对象b;};结束标识;进程2{对象c;};在另一种可选的实施方式中,所述内存泄露检测设备还可以通过编写配置文件来限定所述监控范围。进一步地,所述配置文件可以包括监控范围中的类。在所述应用程序启动之前,所述内存泄露检测设备可以采用代码注入技术读取要加载的所述应用程序的字节码文件(或.class文件),并判断所述字节码中是否存在所述监控范围中的类,若存在,则所述字节码中所述类的入口函数处注入开始文件,以及在所述字节码中所述类的出口函数处注入结束文件。所述内存泄露检测设备即可对所述开始文件之后和结束文件之前创建的对象进行内存泄露的监控。可见,本发明实施例中,所述内存泄露检测设备只监控了所述应用程序在时刻1到时刻2运行范围内的对象,避免监控应用程序中所有的对象,监控的对象的数量级小,内存泄露检测效率高。在另一种可选的实施例中,所述内存泄露检测设备还可以通过代码注入技术跟踪各个对象的创建事件从而获取各个对象的位置信息,并在确定所述内存泄露对象之后,根据获取的位置信息确定所述内存泄露对象的位置。所述位置信息可以包括对象所在的类文件、或者创建对象的具体函数、或者创建对象时所在的行号等。其中,为了避免多线程并发问题,所述内存泄露检测设备可以通过所述jvmti的thread-local机制创建所述各个对象所在线程的分配列表,并调用所述jni函数将所述各个对象的标示符和位置信息传递给所述分配列表,在所述分配列表中存储着多个对象的标示符和位置信息,且同一个对象的标示符和位置信息具有关联关系;或者,所述内存泄露检测设备还可以获取所述应用程序中对象的位置信息,并调用所述jni函数将所述位置信息传递给所述jvmti的预设集合中,在所述预设集合中存储着多个对象的标示符和位置信息,且同一个对象的标示符和位置信息具有关联关系。所述内存泄露检测设备可以调用所述jvmti中已创建的守护线程导出所述分配列表或所述预设集合中的标示符和位置信息,并将导出的所述标示符和位置信息发送给分析程序,以确认所述内存泄露对象的位置。可选地,所述内存泄露检测设备可以先根据上述提供的方案获取所述内存泄露对象的标示符,并在导出的标示符和位置信息中查询所述内存泄露对象的标示符关联的位置信息,最后将查询到的位置信息作为所述内存泄露的位置。举例说明,若所述分配列表如表3所示,即tag_01~tag_05分别关联的位置信息为位置信息1~位置信息5。表3分配列表tag_01位置信息1tag_02位置信息2tag_03位置信息3tag_04位置信息4tag_05位置信息5若根据上述提供的技术方案,所述内存泄露检测设备获取所述内存泄露对象的标示符为tag_03、tag_04和tag_05,那么所述内存泄露检测设备可以将在表3中tag_03、tag_04和tag_05分别关联的位置信息3、位置信息4和位置信息5作为所述内存泄露对象的位置等。可选地,若导出的所述分配列表或所述预设集合中的位置信息存在重复的情况下,所述内存泄露检测设备可以按照上述提供的方案,查询到所述内存泄露对象的位置信息,并将所述内存泄露对象的位置信息中重复的位置信息去掉。举例说明,若所述分配列表如表4所示,存在重复的位置信息3。根据上述提供的方案,若所述内存泄露检测设备获取所述内存泄露对象的标示符为tag_03、tag_04和tag_05,所述内存泄露检测设备可以从表4查询tag_03、tag_04和tag_05分别关联的位置信息3、位置信息3和位置信息5,并将重复的位置信息3去掉,故将位置信息3和位置信息5作为所述内存泄露对象的位置。另外,所述内存泄露检测设备还可以统计所述内存泄露对象的位置信息所关联的对象的数量,并根据所述数量对所述内存泄露对象的位置信息降序排列。结合表4举例说明,内存泄露对象的位置信息3关联的对象的数量为2,内存泄露对象的位置信息5关联的对象的数量为1,所述内存泄露检测设备根据所述数量对所述内存泄露对象的位置信息降序排列:位置信息3、位置信息5。表4分配列表tag_01位置信息1tag_02位置信息2tag_03位置信息3tag_04位置信息3tag_05位置信息5通过本发明实施例提供的技术方案,在导出的所述位置信息出现重复的情况下,所述内存泄露检测设备通过对所述内存泄露对象的位置信息进行去重操作,可以使所述内存泄露对象的位置信息直观上简洁、明了。另外,所述内存泄露检测设备还可以通过创建的守护线程不定时地导出所述位置信息,避免了因所述位置信息都存在于内存中,而导致内存的使用率过高。通过本发明实施例提供的技术方案,所述内存泄露检测设备在确定内存泄露对象的同时,还可以定位所述内存泄露对象的位置,避免了人为地去寻找所述内存泄露对象的位置,提高了内存泄露检测的效率。请参见图3,图3是本发明实施例公开的一种内存泄露检测设备的结构示意图。其中,图3所示的设备可以包括:监控单元301,用于当应用程序在虚拟机上运行时,调用java虚拟机工具接口jvmti监控是否存在对象被回收;其中所述对象关联有标示符;标示符删除单元302,用于在所述监控单元301监控到存在所述对象被回收的情况下,在预设集合中删除所述对象关联的标示符;其中所述预设集合包括多个对象各自关联的标示符;对象确定单元303,用于确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象。其中所述监控单元301,具体用于调用jvmti监控是否存在对象被回收。在一种可选的实施方式中,参见图4所示,所述设备还包括:位置确定单元304,用于通过代码注入技术跟踪各个对象的创建事件从而获取各个对象的位置信息;以及用于所述根据所述预设集合中剩余的标示符确定内存泄露对象之后,根据所述位置信息确定所述内存泄露对象的位置。进一步地,所述位置确定单元304,具体用于通过所述jvmti的thread-local机制创建所述各个对象所在线程的分配列表;以及调用信息传递接口函数将所述各个对象的标示符和位置信息传递给所述分配列表中;其中,所述线程各自关联一个分配列表;所述分配列表包括多个对象各自关联的标示符和位置信息;以及所述分配列表中同一个对象的标示符和位置信息具有关联关系;以及,根据所述分配列表中的位置信息确定所述内存泄露对象的位置。进一步地,所述位置确定单元304,还具体用于调用在所述jvmti中已创建的守护线程导出所述分配列表中的标示符和位置信息;以及根据导出的所述标示符和所述位置信息确定所述内存泄露对象的位置。在另一种可选的实施方式中,参见图5,所述设备还包括:获取单元305,用于获取包括指定目录的启动指令;其中所述启动指令用于启动文件检测线程,所述文件检测线程用于检测所述指定目录下是否存在开始文件或结束文件,其中所述开始文件用于触发启动监控对象的回收情况,所述结束文件用于触发结束监控对象的回收情况;当检测到所述指定目录下存在所述开始文件时,触发执行所述调用jvmti监控是否存在对象被回收的步骤;当检测到所述指定目录下存在所述结束文件时,结束对所述对象的回收情况的监控,并触发执行所述根据所述预设集合中剩余的标示符确定内存泄露对象的步骤。进一步地,所述对象确定单元303,具体用于调用在所述jvmti中已创建的守护线程导出所述预设集合中剩余的标示符;以及根据导出的所述标示符确定内存泄露对象。或者,所述对象确定单元303,还具体用于根据所述预设集合中剩余的标示符和预设的排除对象确定内存泄露对象。本发明实施例可以参考图2所示实施例中相关描述,在此不再赘述。可见,实施图3描述的设备,内存泄露检测设备借助所述jvmti能够监控应用程序中对象是否被回收的能力,检测出所述应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本发明实施例提供的方案减少了人力资源的消耗,提高了内存泄露检测的效率。请参见图6,图6是本发明实施例提供的一种内存泄露检测设备60,所述设备60包括处理器601和存储器602,所述处理器601和存储器602通过总线相互连接。存储器602包括但不限于是随机存取存储器(ram)、只读存储器(rom)、可擦除可编程只读存储器(eprom或者快闪存储器)、或便携式只读存储器(cd-rom),该存储器602用于存储一组程序代码。处理器601可以是一个或多个中央处理器(英文:centralprocessingunit,简称:cpu),在处理器601是一个cpu的情况下,该cpu可以是单核cpu,也可以是多核cpu。所述设备60中的处理器601用于读取所述存储器602中存储的程序代码后,执行以下操作:当应用程序在虚拟机上运行时,调用java虚拟机工具接口jvmti监控是否存在对象被回收;其中所述对象关联有标示符;在监控到存在所述对象被回收的情况下,在预设集合中删除所述对象关联的标示符;其中所述预设集合包括多个对象各自关联的标示符;确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象。在一种可选的实施方式中,调用java虚拟机工具接口jvmti监控是否存在对象被回收。在另一种可选的实施方式中,通过代码注入技术跟踪各个对象的创建事件从而获取各个对象的位置信息;所述根据所述预设集合中剩余的标示符确定内存泄露对象之后,还包括:根据所述位置信息确定所述内存泄露对象的位置。在另一种可选的实施方式中,通过所述jvmti的thread-local机制创建所述各个对象所在线程的分配列表;以及调用信息传递接口函数将所述各个对象的标示符和位置信息传递给所述分配列表中;其中,所述线程各自关联一个分配列表;所述分配列表包括多个对象各自关联的标示符和位置信息;以及所述分配列表中同一个对象的标示符和位置信息具有关联关系;所述根据所述位置信息确定所述内存泄露对象的位置,包括:根据所述分配列表中的位置信息确定所述内存泄露对象的位置。在另一种可选的实施方式中,所述根据所述位置信息确定所述内存泄露对象的位置,包括:调用在所述jvmti中已创建的守护线程导出所述分配列表中的标示符和位置信息;根据导出的所述标示符和所述位置信息确定所述内存泄露对象的位置。在另一种可选的实施方式中,获取包括指定目录的启动指令;其中所述启动指令用于启动文件检测线程,所述文件检测线程用于检测所述指定目录下是否存在开始文件或结束文件,其中所述开始文件用于触发启动监控对象的回收情况,所述结束文件用于触发结束监控对象的回收情况;当检测到所述指定目录下存在所述开始文件时,触发执行所述调用jvmti监控是否存在对象被回收的步骤;当检测到所述指定目录下存在所述结束文件时,结束对所述对象的回收情况的监控,并触发执行所述确定所述预设集合中剩余的标示符中的一个或多个标示符所关联的对象为内存泄露对象的步骤。在另一种可选的实施方式中,所述根据所述预设集合中剩余的标示符确定内存泄露对象,包括:调用在所述jvmti中已创建的守护线程导出所述预设集合中剩余的标示符;根据导出的所述标示符确定内存泄露对象。在另一种可选的实施方式中,所述根据所述预设集合中剩余的标示符确定内存泄露对象,包括:根据所述预设集合中剩余的标示符和预设的排除对象确定内存泄露对象。本发明实施例可以参考图2所示实施例中相关描述,在此不再赘述。可见,实施图6描述的设备,内存泄露检测设备借助所述jvmti能够监控应用程序中对象是否被回收的能力,检测出所述应用程序中未被回收的对象,即所述剩余的标示符关联的对象,并根据所述未被回收的对象确定内存泄露对象。可见,与现有技术中通过人为判断对象实例数量、或对象内存占用大小来找到内存泄露对象相比,本发明实施例提供的方案减少了人力资源的消耗,提高了内存泄露检测的效率。本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,该流程可以由计算机程序来指令相关的硬件完成,该程序可存储于计算机可读取存储介质中,该程序在执行时,可包括如上述各方法实施例的流程。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1