CN101339533A - 基于分区的诊断Java系统的内存泄漏的方法及装置 - Google Patents

基于分区的诊断Java系统的内存泄漏的方法及装置 Download PDF

Info

Publication number
CN101339533A
CN101339533A CNA2007101269848A CN200710126984A CN101339533A CN 101339533 A CN101339533 A CN 101339533A CN A2007101269848 A CNA2007101269848 A CN A2007101269848A CN 200710126984 A CN200710126984 A CN 200710126984A CN 101339533 A CN101339533 A CN 101339533A
Authority
CN
China
Prior art keywords
subregion
memory
mentioned
memory overflow
diagnosing
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CNA2007101269848A
Other languages
English (en)
Other versions
CN101339533B (zh
Inventor
刘天成
李影
龙泉
邱杰
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Priority to CN200710126984A priority Critical patent/CN101339533B/zh
Priority to US12/165,678 priority patent/US8775769B2/en
Publication of CN101339533A publication Critical patent/CN101339533A/zh
Application granted granted Critical
Publication of CN101339533B publication Critical patent/CN101339533B/zh
Expired - Fee Related legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/366Software debugging using diagnostics

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Computer Hardware Design (AREA)
  • Quality & Reliability (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本发明提供一种基于分区的诊断Java系统的内存泄漏的方法,包括:根据分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及如果存在,则判断为该分区可能存在内存泄漏,分析该分区以获取泄漏对象和与泄漏对象关联的对象。根据本发明,Java系统的内存泄漏可以被直接而快速地检测,并且防止了系统由于内存泄漏而崩溃。此外,本发明还提供了基于分区的诊断Java系统的内存泄漏的装置。

Description

基于分区的诊断Java系统的内存泄漏的方法及装置
技术领域
本发明涉及对Java系统的内存泄漏的诊断技术,具体地,涉及基于分区的诊断Java系统的内存泄漏的方法及装置。
背景技术
Java系统的一个重要的优点在于通过垃圾收集器自动管理内存的回收,程序员不需要通过调用函数来释放内存。Java的内存管理是指对象的分配和释放。在Java中,需要通过程序为每个对象申请内存空间,所有对象都在堆内存中分配空间,而对象的释放由垃圾收集器决定和执行。因此,在Java中,内存的分配由程序完成,而内存的释放由垃圾收集器完成,这样,程序员无需担心内存的释放问题。
然而,Java程序可能非故意地保留对某些不再使用的对象的引用,使得Java系统中的垃圾收集器不能回收这些对象所占的内存空间,导致所谓的“内存泄漏”。内存泄漏会引起Java系统的性能下降,严重地甚至会导致程序无法运行或者系统死机。例如,对使用IBM J2EE电子商务软件的客户进行的调查显示,由于内存泄漏,常常导致生产系统崩溃。因此,诊断Java系统的内存泄漏,即找出相关的类(class)和方法(method)等,变得很重要。
在现有技术中,存在以下几种与内存泄漏有关的方法:
(1)第一种方法是:对任务进行内存计算和控制,这可以防止一个任务在运行期间耗尽整个内存。在多任务虚拟机(MVM)中,每个任务都具有一定的被确保的内存量,Kaffe操作系统(KaffeOS)在每一个进程的基础上计算CPU和内存的消耗量。通过计算和控制内存消耗量,即使出现内存泄漏,具有泄漏逻辑的任务或进程也不会独占整个堆内存。这种方法可以在出现内存泄漏的情况下改善运行应用程序的可用性,但是它并不能辨识出内存泄漏的原因,也不能帮助用户找到与内存泄漏有关的源代码。关于上述方法和Kaffe操作系统的具体详情可参见Czajkowski,G.,和Dayn es,L.所发表的“Multitasking without compromise:a virtual machineevolution”,Object-Oriented Programming,Systems,Languages,andApplications(OOPSLA’01),2001年11月和G.Back,W.Hsieh和J.Lepreau所发表的“Processes in KaffeOS:Isolation,resource management,and sharing in Java”,Proceedings of the Fourth Symposium on OperatingSystem Design and Implementation(OSDI’2000),圣地亚哥,加州,美国,2000年。
(2)第二种方法是:根据某些特征和规则对源代码进行静态或基于简档的分析,以发现潜在的内存泄漏。目前,研究人员对这一类方法已经进行了大量的探索,例如参见R.Shaham,E.K.Kolodner和M.Sagiv所发表的“Automatic removal of array memory leaks in Java”,D.A.Watt,Editor,Compiler Construction,9th International Conference,Volume 1781of Lecture Notes in Computer Science,第50-66页,柏林,德国,2000年3月和T.Chilimbi和M.Hauswirth所发表的“Low-overhead memory leakdetection using adaptive statistical profiling”,Proceedings of theSymposium on Architectural Support for Proramming Languages andOperating Systems(ASPLOS),2004年10月。
但是在Java中,内存泄漏实际上是语义相关的,因此,对特征和规则的定义很困难,并且不正确的定义会导致错误的报告。而且,如果没有强调方法对象调用的时间顺序,则很难确定变量是否引用了泄漏对象。
(3)第三种方法是基于运行信息的方法,其分析堆内存的快照,以选出泄漏对象的候选。具体详情可参见Nick Mitchell和Gary Sevitsky所发表的“LeakBot:An Automated and Lightweight Tool for DiagnosingMemory Leaks in Large Java Applications”,European Conference onObject-oriented Computing(ECOOP),2003年7月。然而该方法产生大量的有关各个对象的低级别的信息,这需要大量的分析时间,并且无法帮助用户找到与内存泄漏有关的源代码。
发明内容
本发明正是基于上述技术问题而提出的,其目的在于提供一种基于分区的诊断Java系统的内存泄漏的方法和装置,可以快速地诊断内存泄漏,防止系统由于内存泄漏而崩溃,并能找出引起内存泄漏的源代码,方便了对内存泄漏的修复。
根据本发明的一个方面,提供一种基于分区的诊断Java系统的内存泄漏的方法,包括:根据分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及如果存在,则判断为该分区可能存在内存泄漏,分析该分区以获取泄漏对象和与泄漏对象关联的对象。
根据本发明的另一个方面,提供一种基于分区的诊断Java系统的内存泄漏的装置,包括:分区单元,用于根据分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;检测器,用于检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及分析器,用于分析内存空间被耗尽的分区以获取泄漏对象和与泄漏对象关联的对象。
附图说明
图1是根据本发明的一个实施例的基于分区的诊断Java系统的内存泄漏的方法的流程图;
图2是根据本发明的另一个实施例的基于分区的诊断Java系统的内存泄漏的方法的流程图;
图3是示出两个分区所有者的示意图;
图4是基于J9虚拟机内存空间的分区的结构的示意图;
图5是示出通过JVM TI标签实现的堆内存的分区的示意图;
图6是根据本发明的实施例的基于分区的诊断Java系统的内存泄漏的装置的方框图。
具体实施方式
相信通过下面结合附图对本发明的具体实施方式的详细说明,本发明的上述和其它目的、特征和优点将变得更加明显。
图1是根据本发明的一个实施例的基于分区的诊断Java系统的内存泄漏的方法的流程图。
如图1所示,首先在步骤110,根据分区策略,Java虚拟机的堆内存被划分成多个分区,其中每个分区具有至少一个分区所有者。
分区策略是用于定义分区所有者的配置文件,其相应地定义分区和分区的大小。因此,分区策略至少包含分区所有者和分区的大小。作为一个分区的分区所有者,其创建的对象都被分配在该分区中。
分区策略可以预先由用户生成,也可以通过分析源程序代码确定。具体的生成分区策略的方法,将在后面的实施例中详细描述。
这样,在分区策略的基础上,Java虚拟机的堆内存可以进行分区操作。关于Java虚拟机的堆内存的分区操作,将在后面的实施例中详细描述。
然后,在步骤120,检测被划分的各个分区的状态以确定是否存在某一个分区的内存空间被耗尽。通过检测分区的状态,可以知道每个分区的使用情况。当某一个分区的内存空间将被耗尽时,对该分区的对象分配请求会产生内存溢出错误(OutOfMemoryError)信号。因此,通过检测该信号是否出现,可以知道分区的内存空间是否被耗尽。
当存在某一个分区的内存空间被耗尽时,判断为在该分区可能存在内存泄漏。然后,在步骤130,进一步分析该分区,以获取泄漏对象和与泄漏对象关联的对象。例如,可以采用现有工具中的LeakBot分析分区。
在本实施例中,泄漏对象是指在发生内存泄漏时被引用的时间比所需要的时间长的对象,与泄漏对象关联的对象包括:直接或间接引用泄漏对象的对象和/或创建泄漏对象的对象。
如果不存在某一个分区的内存空间被耗尽,则重复执行步骤120。
通过以上描述可以看出,本实施例的基于分区的诊断Java系统的内存泄漏的方法通过对Java虚拟机的堆内存进行分区并检测这些分区的内存空间是否耗尽,可以直接而快速地诊断Java系统是否存在内存泄漏,并且,通过堆内存的分区,使得在某一个分区中的内存泄漏不会影响其它分区的运行,从而使整个Java虚拟机也能够保持运行。
图2是根据本发明的另一个实施例的基于分区的诊断Java系统的内存泄漏的方法的流程图。下面结合附图详细说明本实施例。
如图2所示,首先,在步骤101,生成或者获取Java虚拟机的堆内存的分区策略。如上所述,分区策略是用于定义分区所有者的配置文件,其相应地定义分区和分区的大小。因此,分区策略至少包含分区所有者和分区的大小。作为一个分区的分区所有者,其创建的对象都被分配在该分区中。分区所有者可以是Java中的包(package)、类(class)或者方法(method)等。
分区策略可以由用户预先根据其目的生成。通常,分区是基于应用程序的逻辑结构而定义的,例如,在J2EE应用程序中,可以将每个Servlet(小服务程序)和EJB(Java企业构件)定义为分区所有者,那么,由这些分区所有者创建的对象都在对应的分区内分配内存。然后,根据所获取的分区所有者的行为,可以确定各个分区的大小。由于每个分区所有者的各自的行为对其所使用的内存空间的影响较大,因此,通常需要一组测试用例来确定合适的分区大小。
可选地,还可以通过分析应用程序的源代码来生成分区策略。具体地,首先,对应用程序的源代码执行逃逸(escape)分析以获取源代码中所有对象之间关于内存泄漏的潜在关系。通俗地说,对象逃逸是指对象的生命周期超过了创建该对象的对象,例如线程或方法等。关于对象的逃逸的正式定义可参照J.Choi,M.Gupta,M.Serrano,V.Sreedhar和S.Midkiff所著的“Escape analysis for Java”,In Object-Oriented Programming,System,Languages and Applications,1999。导致对象逃逸的原因是存在没有在引用目标对象的对象中创建的对象。然后,根据逃逸分析的结果,计算每两个对象之间的距离,并且根据所计算的距离,将所有对象聚类成多个组,并为每个组分配一个内存空间,即分区。在本实施例中,聚类可以采用谱聚类方法,可参见A.Y.Ng,M.Jordan和Y.Weiss所著的“On SpectralClustering:Analysis and an Algorithm”,In Advances in NeuralInformation Processing Systems,2001。最后,根据每个分区所包含的对象,确定每个分区的分区所有者及其大小。
下面通过具体的实例说明分区策略。
实例1:示出了在方法级别上定义一个分区所有者的分区策略的例子。如下所示的分区策略定义了一个分区,其名称为“HelloPar”,大小为10K,其分区所有者是类com.ibm.jpar.runtime.test.HelloWorld的方法say(String)。
<partition>
            <name>HelloPar</name>
            <size>10000</size>
            <methods>
                <class-name>com.ibm.jpar.runtime.test.HelloWorld</class-name>
                <method-name>say</method-name>
                <method-params>java.lang.String</method-params>
            </methods>
</partition>
当运行应用程序时,在方法say(String)条目处,线程绑定分区被跳转到属于该分区所有者say(String)的分区。
实例2:示出了一个分区具有多个分区所有者的分区策略的例子。如下所示的分区策略定义了具有两个分区所有者的分区,其中一个分区所有者是类com.ibm.jpar.runtime.test.HelloWorld的方法say(String),另一个分区所有者是类com.ibm.jpar.runtime.test.HelloWorld的方法echo。
<partition>
            <name>HelloEchoPar</name>
            <size>20000</size>
            <methods>
                <class-name>com.ibm.jpar.runtime.test.HelloWorld</class-name>
                <method-name>say</method-name>
                <method-params>java.lang.String</method-params>
            </methods>
            <methods>
                <class-name>com.ibm.jpar.runtime.test.Echo</class-name>
                <method-name>echo</method-name>
                <method-params>java.lang.String</method-params>
            </methods>
</partition>
实例3:示出了在类级别上定义分区或者分区所有者的分区策略的例子。为了在更高级别(例如,类级别)上定义分区或者分区所有者,需要使用通配符wildcard(*)。如下所示的分区策略定义了分区所有者是类com.ibm.jpar.tuntime.test.HelloWorld的分区。
<partition>
            <name>HelloPar</name>
            <size>15000</size>
            <methods>
                <class-name>com.ibm.jpar.runtime.test.HelloWorld</class-name>
                <method-name>*</method-name>
                <method-params>*</method-params>
            </methods>
</partition>
返回图2,在生成或者获取了分区策略(步骤101)之后,根据该分区策略,Java虚拟机的堆内存可以被划分成多个分区(步骤110)。
例如,如果分区策略是线程绑定的策略,那么,分区是与线程绑定的内存空间,分区所有者是线程,且由各线程创建的所有对象都被分配在该线程绑定分区中。如果在应用程序运行时,当前线程执行了另一个分区所有者的方法,则线程绑定分区和分区所有者将改变。图3示出了两个分区所有者的示意图。如图3所示,Java虚拟机堆内存被划分成两个分区:分区1和分区2。分区1的分区所有者1创建了5个对象,这5个对象都被分配在分区1中。分区1中的对象5创建分区2的分区所有者2,则线程绑定分区被跳转到分区2,分区所有者2创建2个对象,这2个对象都分配在分区2中。
下面详细描述了两种实现堆内存的分区的方式,当然,本领域的技术人员知道还可以采用其它方式实现堆内存的分区。
实施方式1:基于J9虚拟机内存空间的实现
图4是基于J9虚拟机内存空间的分区的结构的示意图。J9虚拟机的内存空间机制很适合于堆内存的分区。作为堆内存分配的单元的内存空间管理直接处理对象分配请求的物理内存。一个内存空间不能使用其它内存空间的物理内存。J9虚拟机中的资源管理类库jclRM提供内存空间的应用程序编程接口(API)以进行一些基本的管理操作,包括内存空间的创建、解构等。
如图4所示,在该分区结构中,有4个分区所有者,分区所有者是线程。如上所述,在分区策略中定义了分区所有者和相应的内存空间(分区)的大小。那么,根据分区策略,可以在应用程序起动时,经由资源管理类库jclRM通过调用createMemeorySpace(创建内存空间)方法来分别创建与各个分区所有者对应的内存空间(分区),其大小如分区策略中所定义的。这样,每个线程都与一个内存空间相关联,由一个线程所创建的所有对象将被分配在与该线程相关联的内存空间中。
在图4所示的结构中,在应用程序的线程与对应的内存空间(分区)之间,还存在线程-内存空间跳转器(TMSS)。TMSS包括注入在Java虚拟机中装载的类的构件。所注入的代码可以经由资源管理类库jclRM提供的接口通过调用setCurrentMemeorySpace(设置当前内存空间)方法来跳转线程绑定的内存空间。每当应用程序的执行路径通过一个分区所有者与另一个分区所有者的边界时,TMSS触发所注入的代码以跳转线程绑定的内存空间。
因此,应用程序运行时的工作流程如下:首先,起动应用程序,读取分区策略,并对分区策略中的每个分区所有者创建内存空间作为分区。接着,注入分区所有者的类,插入线程绑定的内存空间代码,然后调用应用程序的主方法。当应用程序停止时,所有的内存空间也可以经由资源管理类库jclRM接口通过调用destroyMemorySpaces(释放内存空间)方法来解构。
实施方式2:基于Java虚拟机工具接口的实现
Java虚拟机工具接口(JVM TI)是由开发和监视工具使用的编程接口,其可以检查在Java虚拟机中运行的应用程序的状态和控制应用程序的执行,并且JVM TI提供了一组在运行时允许与对象一起操作的堆接口。
JVM TI使得对象可以与一个值(标签)相关联,该标签可以通过使用SetTag(设置标签)方法或者通过诸如jvmtiHeapObjectCallback的回调方法设置。这样,堆内存的分区可以通过使用标签来实现。首先,每个分区被提供一个标识符ID,那么,仅当一个对象附带有具有某个分区的分区ID的标签时,才表示该对象属于该分区。
在运行应用程序时,在堆内存中的一个分区中的对象可以不在一个连续的内存空间内,而是通过标签聚集在一起。图5是示出通过JVM TI标签实现的堆内存的分区的示意图。如图5所示,与值为1的标签对应的对象地址都属于分区1,与值为2的标签对应的对象地址都属于分区2,与值为3的标签对应的对象地址都属于分区3,尽管在同一个分区中的对象的地址不是连续的。
分区的已使用大小可以通过由JVM TI接口调用GetObjectsWithTags(获取具有标签的对象)方法获取该分区中所有的对象及其大小来获得。
因此,基于Java虚拟机工具接口实现的线程绑定分区可以通过如下步骤实现:在应用程序运行时,动态地创建具有标识符ID的分区,使得对每一个线程都有一个线程绑定分区;每当分配一个对象时,该对象都被附加上所属的线程绑定分区的分区ID作为标签。进一步地,线程绑定分区在运行时可通过调用setCurrentPartition(设置当前分区)方法来改变。
另外,JVM TI还可以跟踪对象的分配,这可以通过注入字节码实现。字节码注入可用于在字节码中跟踪对象分配。当对象被创建时调用VMObiectAlloc事件回调函数,这样,该分配不会通过其它注入机制检测。
此外,本领域的普通技术人员容易知道,除了上述的两种实现堆内存的分区的方式之外,还可以采用其它的方式来实现分区。实际上,用于实现堆内存的分区的方式只要能够实现以下两点即可:(1)记录分区与对象之间的一对多关系;(2)获取一个分区中的所有对象的大小并相加,从而得到分区的大小。例如,可以使用二维表维护分区与对象之间的关系,具体包括:通过注入字节码来截取对象的分配,然后,根据当前线程的调用栈确定分配的对象所对应的分区并更新对应的二维表项,最后通过Java语言提供的接口获取对象的大小并更新对应分区的大小。
返回图2,然后,在步骤120,检测被划分的各个分区的状态以确定是否存在某一个分区的内存空间被耗尽。如上所述,可以通过检测在某个分区中是否出现内存溢出错误(OutOfMemoryError)信号来确定分区的内存空间是否被耗尽。
当存在某一个分区的内存空间被耗尽时,判断为在该分区可能存在内存泄漏。然后,在步骤130,进一步分析该分区,以获取泄漏对象和与泄漏对象关联的对象。例如,可以采用现有工具中的LeakBot分析分区。
在本实施例中,泄漏对象是指在发生内存泄漏时被引用的时间比所需要的时间长的对象,与泄漏对象关联的对象包括:直接或间接引用泄漏对象的对象和/或创建泄漏对象的对象。
如果不存在某一个分区的内存空间被耗尽,则重复执行步骤120。
进一步地,根据所获取的泄漏对象和与泄漏对象关联的对象,分析应用程序的源代码以获取与内存泄漏相关的代码段(步骤140)。
在本实施例中,分析源代码的方法是静态检查方法。具体地,根据泄漏对象和与泄漏对象关联的对象,跟踪源代码中引用这些对象的变量以标识出潜在的泄漏引用,即,在应用程序源代码中,找到与上述泄漏对象和与泄漏对象关联的对象相关的表达式(包括变量和字段),对其进行引用计数分析,这可以通过例如固定点(Fixpoint)迭代法实现,引用计数在源代码的各个程序语句中都存在的对象引起内存泄漏的可能性更大,那么,与这样的对象对应的引用被标识为泄漏引用。该引用计数分析的结果可以表明哪些对象更可能是引起内存泄漏的源,从而缩小泄漏对象的范围。然后,提取所标识的潜在的泄漏引用的引用模式以确定作为内存泄漏的源的泄漏引用,即,对所标识的潜在的泄漏引用进行最后访问分析,以获取这些潜在的泄漏引用的使用情况,如果某个潜在的泄漏引用长时间没有被使用,则确定该泄漏引用是内存泄漏的源。最后,跟踪被确定为内存泄漏的源的泄漏引用的访问命令,以确定添加释放该泄漏引用的释放语句的正确位置,从而获取与内存泄漏相关的源代码段。
此外,在获得了与内存泄漏相关的源代码段之后,还可以进一步判断是否需要再分区,例如,判断与内存泄漏相关的源代码段是否太多而使得用户不易对源代码段进行修复。
如果需要再分区,则根据源代码分析的结果,生成新的分区策略(步骤150)。具体地,首先,将除了在步骤120检测到的内存空间被耗尽的分区以外的其它分区合并为一个分区;然后,分析上述的内存空间被耗尽的分区所对应的源代码,根据前面描述的通过分析源代码生成分区策略的方法,生成上述的内存空间被耗尽的分区的分区策略,从而获得新的分区策略。然后,根据新的分区策略,对Java虚拟机的堆内存重复进行如上所述的分区(步骤110)、分区状态检测(步骤120)、分区分析(步骤130)和源代码分析(步骤140)。这样,根据新的分区策略,Java虚拟机的堆内存可以被进一步地分区,以便更准确地定位内存泄漏。
此外,本领域的普通技术人员知道,在需要再分区时,还可以保持原来的分区策略不变(步骤150),对在步骤120中检测为内存空间被耗尽的分区重复进行如上所述的分区(步骤110)、分区状态检测(步骤120)、分区分析(步骤130)和源代码分析(步骤140),从而能够更准确地定位内存泄漏。
如果不需要再分区,则结束此次诊断内存泄漏的过程。
通过以上描述可以看出,本实施例的基于分区的诊断Java系统的内存泄漏的方法具有以下的优点:
1.直接而快速地诊断内存泄漏:本实施例对Java虚拟机的堆内存进行分区,并基于这些分区,通过检测分区的内存空间是否耗尽来检测内存泄漏,因此,如果发生内存泄漏,则可以直接而快速地检测到。
2.防止系统由于内存泄漏而崩溃:由于每个分区所有者只能将其创建的对象在自己的分区范围内分配,因此,在某一个分区中的内存泄漏不会影响其它分区,即使发生内存泄漏,整个Java虚拟机也能够保持运行。
3.可以分析应用程序源代码,以确定与内存泄漏相关的源代码段,从而方便用户修复应用程序中引起内存泄漏的源代码。
在同一发明构思下,图6是根据本发明的实施例的基于分区的诊断Java系统的内存泄漏的装置的示意性框图。
如图6所示,本实施例的基于分区的诊断Java系统的内存泄漏的装置600包括:用于生成分区策略的分区策略生成器601;分区单元602,其根据所生成的分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;检测器603,其检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及分区分析器604,用于分析内存空间被耗尽的分区以获取泄漏对象和与泄漏对象关联的对象。
如上所述,分区策略至少包括分区所有者和分区的大小。在本实施例中,分区策略生成器601通过分析应用程序的源代码来生成分区策略,其包括:对象逃逸分析器6011,用于对应用程序的源代码执行逃逸分析以获取源代码中所有对象之间的潜在关系;距离计算单元6012,其根据对象逃逸分析器6011的分析结果,计算每两个对象之间的距离;聚类单元613,其根据所计算的距离,将所有对象聚类为多个组,其中,每个组对应一个分区;以及确定单元6014,用于确定每个分区的所有者和大小。
可选地,分区策略也可以由用户预先根据其目的生成,并直接提供给分区单元602。在这种情况下,分区策略生成器601可以设置在基于分区的诊断Java系统的内存泄漏的装置600的外部,其可以包括:分区定义单元,用于根据应用程序的逻辑结构定义分区,以获得分区所有者;以及分区大小确定单元,用于根据所获得的分区所有者的行为,确定各个分区的大小。
由分区策略生成器601生成的分区策略或者来自用户的预先生成的分区策略被提供给分区单元602,由分区单元602将Java虚拟机堆内存划分为多个分区。在具体的实现中,如果Java虚拟机支持分区功能,则分区单元602可以不作为单独的单元;如果Java虚拟机不支持分区功能,则分区单元602通过相应的接口与Java虚拟机连接,从而实现对堆内存分区的功能。
然后,检测器603检测各个分区的状态,该状态与该分区的内存空间的使用有关。当检测器603检测到某个分区出现OutOfMemoryError信号时,则确定该分区的内存空间将被耗尽,这表明在该分区可能发生了内存泄漏。
然后,分区分析器604对可能发生内存泄漏的分区进行分析,获取泄漏对象和与泄漏对象关联的对象。例如,分区分析器604可以使用现有工具中的LeakBot分析分区。
进一步地,本实施例的基于分区的诊断Java系统的内存泄漏的装置600还包括:源代码分析器605,其根据由分区分析器604获取的泄漏对象和与泄漏对象关联的对象,分析应用程序的源代码以获取与内存泄漏有关的代码段。
具体地,当所获取的泄漏对象和与泄漏对象关联的对象(包括类型)作为输入被提供给源代码分析器605时,首先,由变量跟踪单元6051跟踪源代码中引用这些对象的变量以标识出潜在的泄漏引用,即,在应用程序源代码中,找到与这些泄漏对象和与泄漏对象关联的对象相关的表达式(包括变量和字段),并对其进行引用计数分析,获得与引用计数在一系列程序命令中持续存在的对象对应的引用,并标识为潜在的泄漏引用。然后,由提取单元6052提取所标识的潜在的泄漏引用的引用模式,即,对所标识的潜在的泄漏引用进行最后访问分析,以获取这些潜在的泄漏引用的使用情况,如果某个潜在的泄漏引用长时间没有被使用,则确定该泄漏引用是内存泄漏的源。然后,由源代码修复单元6053跟踪被确定为内存泄漏的源的泄漏引用的访问命令,以确定添加用于释放该泄漏引用的释放语句的正确位置,从而获取与内存泄漏相关的源代码段。
此外,本实施例的基于分区的诊断Java系统的内存泄漏的装置600还可以包括:判断单元606,其根据源代码分析器605的分析结果,判断是否需要再分区;以及合并单元607,其将由检测器603检测为内存空间被耗尽的分区以外的分区合并为一个分区。
当判断单元606判断为需要再分区时,合并单元607将除了内存空间被耗尽的分区以外的其它分区合并为一个分区,然后,由分区策略生成器601对内存空间被耗尽的分区生成新的分区策略,或者保持原来的分区策略不变,并提供给分区单元602。分区单元602利用新的分区策略或者原来的分区策略,对Java虚拟机的堆内存中由检测器603检测为内存空间被耗尽的分区进行再分区。本实施例的基于分区的诊断Java系统的内存泄漏的装置600及其组件可以由诸如超大规模集成电路或门阵列、诸如逻辑芯片、晶体管等的半导体、或者诸如现场可编程门阵列、可编程逻辑设备等的可编程硬件设备的硬件电路实现,也可以用由各种类型的处理器执行的软件实现,也可以由上述硬件电路和软件的结合实现。本实施例的基于分区的诊断Java系统的内存泄漏的装置600在操作上实现图2所示的实施例的基于分区的诊断Java系统的内存泄漏的方法。
通过以上描述可以看出,采用本实施例的基于分区的诊断Java系统的内存泄漏的装置600,由于对Java虚拟机的堆内存进行分区,并以分区为单位检测是否发生内存耗尽,因此,可以直接而快速地诊断出是否发生内存泄漏,并防止Java系统由于内存泄漏而死机。而且,可以进一步分析应用程序的源代码以确定源代码中与内存泄漏相关的源代码段,从而方便用户修正应用程序中引起内存泄漏的源代码。
虽然以上结合具体实施方式对本发明的基于分区的诊断Java系统的内存泄漏的方法和装置进行了详细描述,但本发明并不限于此,在不脱离本发明的范围的情况下,可以对本发明进行多种变换、替换和修改。

Claims (17)

1.一种基于分区的诊断Java系统的内存泄漏的方法,包括:
根据分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;
检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及
如果存在,则判断为该分区可能存在内存泄漏,分析该分区以获取泄漏对象和与泄漏对象关联的对象。
2.根据权利要求1所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述分区策略至少包括:分区所有者和分区的大小。
3.根据权利要求1或2所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述分区策略通过以下步骤生成:
根据应用程序的逻辑结构定义分区,以获得分区所有者;以及
根据所获得的分区所有者的行为,确定各个分区的大小。
4.根据权利要求1或2所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述分区策略通过以下的步骤生成:
对应用程序的源代码执行逃逸分析以获取源代码中所有对象之间的潜在关系;
根据上述逃逸分析的结果,计算每两个对象之间的距离;
根据所计算的距离,将所有对象聚类为多个组,其中,每个组对应一个分区;以及
确定每个分区的所有者和大小。
5.根据权利要求1至4任意一项所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述检测的步骤包括:
检测上述各个分区是否出现内存溢出错误信号;以及
如果出现,则表明该分区的内存空间被耗尽。
6.根据权利要求1至5任意一项所述的基于分区的诊断Java系统的内存泄漏的方法,还包括:
根据所获取的泄漏对象和与泄漏对象关联的对象,分析应用程序的源代码以获取与内存泄漏相关的代码段。
7.根据权利要求6所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述分析应用程序的源代码的步骤包括:
根据所获取的泄漏对象和与泄漏对象关联的对象,跟踪源代码中引用这些对象的变量以标识出潜在的泄漏引用;
提取所标识的潜在的泄漏引用的引用模式以获取被确定为内存泄漏的源的泄漏引用;以及
跟踪被确定为内存泄漏的源的泄漏引用的访问命令,以确定添加用于释放该泄漏引用的释放语句的正确位置。
8.根据权利要求6或7所述的基于分区的诊断Java系统的内存泄漏的方法,还包括:
根据上述分析源代码的结果,判断是否需要再分区;
如果需要再分区,则生成新的分区策略或者保持原来的分区策略不变;以及
利用上述新的分区策略或者上述保持不变的原来的分区策略,对上述堆内存或者上述检测为内存空间被耗尽的分区执行上述分区、分区状态检测、分区分析和源代码分析的步骤。
9.根据权利要求8所述的基于分区的诊断Java系统的内存泄漏的方法,其中,所述生成新的分区策略的步骤包括:
将上述检测为内存空间被耗尽的分区以外的分区合并为一个分区;以及
分析上述内存空间被耗尽的分区所对应的源代码,以生成上述内存空间被耗尽的分区的分区策略。
10.一种基于分区的诊断Java系统的内存泄漏的装置,包括:
分区单元,用于根据分区策略,将Java虚拟机的堆内存划分成多个分区,其中每个分区具有至少一个分区所有者;
检测器,用于检测上述各个分区的状态以确定是否存在某一个分区的内存空间被耗尽;以及
分区分析器,用于分析内存空间被耗尽的分区以获取泄漏对象和与泄漏对象关联的对象。
11.根据权利要求10所述的基于分区的诊断Java系统的内存泄漏的装置,还包括:分区策略生成器,用于生成分区策略。
12.根据权利要求11所述的基于分区的诊断Java系统的内存泄漏的装置,其中,所述分区策略生成器包括:
分区定义单元,用于根据应用程序的逻辑结构定义分区,以获得分区所有者;以及
分区大小确定单元,用于根据所获得的分区所有者的行为,确定各个分区的大小。
13.根据权利要求11所述的基于分区的诊断Java系统的内存泄漏的装置,其中,所述分区策略生成器包括:
对象逃逸分析器,用于对应用程序的源代码执行逃逸分析以获取源代码中所有对象之间的潜在关系;
距离计算单元,用于根据上述逃逸分析的结果,计算每两个对象之间的距离;
聚类单元,用于根据所计算的距离,将所有对象聚类为多个组,其中,每个组对应一个分区;以及
确定单元,用于确定每个分区的所有者和大小。
14.根据权利要求10至13任意一项所述的基于分区的诊断Java系统的内存泄漏的装置,其中,所述检测器通过检测内存溢出错误信号来确定是否存在某一个分区的内存空间被耗尽。
15.根据权利要求10至14任意一项所述的基于分区的诊断Java系统的内存泄漏的装置,还包括:
源代码分析器,用于根据所获取的泄漏对象和与泄漏对象关联的对象,分析应用程序的源代码以获取与内存泄漏相关的代码段。
16.根据权利要求10至15任意一项所述的基于分区的诊断Java系统的内存泄漏的装置,其中,所述源代码分析器包括:
变量跟踪单元,用于根据所获取的泄漏对象和与泄漏对象关联的对象,跟踪源代码中引用这些对象的变量以标识出潜在的泄漏引用;
提取单元,用于提取所标识的泄漏引用的引用模式,以获取被确定为内存泄漏的源的泄漏引用;以及
源代码修复单元,用于跟踪被确定为内存泄漏的源的泄漏引用的访问命令,以确定添加用于释放该泄漏引用的释放语句的正确位置。
17.根据权利要求15或16所述的基于分区的诊断Java系统的内存泄漏的装置,还包括:
判断单元,用于根据上述源代码分析器的分析结果,判断是否需要再分区;以及
合并单元,用于在上述判断单元的判断结果为需要再分区时,将由上述检测器检测为内存空间被耗尽的分区以外的分区合并为一个分区;
其中,在上述判断单元的判断结果为需要再分区的情况下,上述分区策略生成器对上述内存空间被耗尽的分区生成新的分区策略,或者保持原来的分区策略不变,并提供给上述分区单元;
上述分区单元利用上述新的分区策略或者上述保持不变的原来的分区策略,对上述内存空间被耗尽的分区进行再分区。
CN200710126984A 2007-07-04 2007-07-04 基于分区的诊断Java系统的内存泄漏的方法及装置 Expired - Fee Related CN101339533B (zh)

Priority Applications (2)

Application Number Priority Date Filing Date Title
CN200710126984A CN101339533B (zh) 2007-07-04 2007-07-04 基于分区的诊断Java系统的内存泄漏的方法及装置
US12/165,678 US8775769B2 (en) 2007-07-04 2008-07-01 Partition-based method and apparatus for diagnosing memory leak in java systems

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN200710126984A CN101339533B (zh) 2007-07-04 2007-07-04 基于分区的诊断Java系统的内存泄漏的方法及装置

Publications (2)

Publication Number Publication Date
CN101339533A true CN101339533A (zh) 2009-01-07
CN101339533B CN101339533B (zh) 2012-10-10

Family

ID=40213604

Family Applications (1)

Application Number Title Priority Date Filing Date
CN200710126984A Expired - Fee Related CN101339533B (zh) 2007-07-04 2007-07-04 基于分区的诊断Java系统的内存泄漏的方法及装置

Country Status (2)

Country Link
US (1) US8775769B2 (zh)
CN (1) CN101339533B (zh)

Cited By (11)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN102662825A (zh) * 2012-02-22 2012-09-12 中国人民解放军国防科学技术大学 一种面向堆操作程序的内存泄漏检测方法
CN102968380A (zh) * 2012-11-02 2013-03-13 深圳市同洲电子股份有限公司 内存文件系统中内存分区的管理方法和装置
CN103631662A (zh) * 2013-12-20 2014-03-12 普元信息技术股份有限公司 复杂事件处理云平台事件分析引擎容量评估的系统及方法
CN103716234A (zh) * 2013-12-19 2014-04-09 汉柏科技有限公司 一种定位报文内存泄露的方法
CN104778087A (zh) * 2014-01-09 2015-07-15 中国移动通信集团山东有限公司 一种信息处理方法以及信息处理装置
CN105260174A (zh) * 2015-09-16 2016-01-20 北京航空航天大学 实时Java虚拟机中基于等价类的对象内存状态的记录跟踪方法
CN105607912A (zh) * 2015-12-24 2016-05-25 华为技术服务有限公司 一种Java对象分配优化方法、装置及设备
CN108073441A (zh) * 2016-11-14 2018-05-25 阿里巴巴集团控股有限公司 一种虚拟机内存监管方法与设备
CN111274060A (zh) * 2020-02-10 2020-06-12 广州虎牙科技有限公司 一种确定内存异常的方法、装置、设备和存储介质
CN112835765A (zh) * 2021-02-02 2021-05-25 中国工商银行股份有限公司 一种Java程序内存使用情况监控方法及装置
CN113742080A (zh) * 2020-09-10 2021-12-03 吕戈 一种高效的不可变对象执行环境的构建方法及装置

Families Citing this family (12)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101639804A (zh) * 2008-07-29 2010-02-03 国际商业机器公司 确定程序中的内存泄漏位置的方法和装置
JP2010072854A (ja) * 2008-09-17 2010-04-02 Canon Inc 情報処理装置の支援装置、支援方法、およびコンピュータプログラム
US10133557B1 (en) * 2013-01-11 2018-11-20 Mentor Graphics Corporation Modifying code to reduce redundant or unnecessary power usage
US9330119B2 (en) 2013-04-11 2016-05-03 Oracle International Corporation Knowledge intensive data management system for business process and case management
US10740358B2 (en) 2013-04-11 2020-08-11 Oracle International Corporation Knowledge-intensive data processing system
US9361140B1 (en) * 2014-12-11 2016-06-07 International Business Machines Corporation Isolating applications in server environment
US10248561B2 (en) 2015-06-18 2019-04-02 Oracle International Corporation Stateless detection of out-of-memory events in virtual machines
US10534643B2 (en) 2016-05-09 2020-01-14 Oracle International Corporation Correlation of thread intensity and heap usage to identify heap-hoarding stack traces
US10929270B2 (en) * 2018-01-01 2021-02-23 Rookout Ltd. System and method for controlled data extraction in computer networks
CN113448735A (zh) * 2021-07-16 2021-09-28 维沃移动通信有限公司 内存泄露处理方法、装置和电子设备
CN113886114B (zh) * 2021-09-03 2023-09-01 上海弘积信息科技有限公司 一种内存泄漏的定位方法
US11789845B2 (en) 2021-10-15 2023-10-17 International Business Machines Corporation Software object identification using record generating code insertion

Family Cites Families (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6275916B1 (en) 1997-12-18 2001-08-14 Alcatel Usa Sourcing, L.P. Object oriented program memory management system and method using fixed sized memory pools
AU2158900A (en) * 1998-11-25 2000-06-19 Sun Microsystems, Inc. A method for enabling comprehensive profiling of garbage-collected memory systems
US6370684B1 (en) * 1999-04-12 2002-04-09 International Business Machines Corporation Methods for extracting reference patterns in JAVA and depicting the same
CN1248114C (zh) * 2002-06-20 2006-03-29 华为技术有限公司 一种软件内存泄露的检查方法
US7234080B2 (en) * 2002-10-18 2007-06-19 Computer Associates Think, Inc. Locating potential sources of memory leaks
US7257692B2 (en) 2003-10-01 2007-08-14 Lakeside Software, Inc. Apparatus and method for detecting memory leaks
GB0515405D0 (en) * 2005-07-27 2005-08-31 Ibm Memory leak detection
US8490065B2 (en) * 2005-10-13 2013-07-16 International Business Machines Corporation Method and apparatus for software-assisted data cache and prefetch control

Cited By (18)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN102662825A (zh) * 2012-02-22 2012-09-12 中国人民解放军国防科学技术大学 一种面向堆操作程序的内存泄漏检测方法
CN102662825B (zh) * 2012-02-22 2014-07-16 中国人民解放军国防科学技术大学 一种面向堆操作程序的内存泄漏检测方法
CN102968380A (zh) * 2012-11-02 2013-03-13 深圳市同洲电子股份有限公司 内存文件系统中内存分区的管理方法和装置
CN103716234B (zh) * 2013-12-19 2017-11-28 汉柏科技有限公司 一种定位报文内存泄露的方法
CN103716234A (zh) * 2013-12-19 2014-04-09 汉柏科技有限公司 一种定位报文内存泄露的方法
CN103631662B (zh) * 2013-12-20 2017-09-26 普元信息技术股份有限公司 复杂事件处理云平台事件分析引擎容量评估的系统及方法
CN103631662A (zh) * 2013-12-20 2014-03-12 普元信息技术股份有限公司 复杂事件处理云平台事件分析引擎容量评估的系统及方法
CN104778087A (zh) * 2014-01-09 2015-07-15 中国移动通信集团山东有限公司 一种信息处理方法以及信息处理装置
CN104778087B (zh) * 2014-01-09 2019-04-12 中国移动通信集团山东有限公司 一种信息处理方法以及信息处理装置
CN105260174A (zh) * 2015-09-16 2016-01-20 北京航空航天大学 实时Java虚拟机中基于等价类的对象内存状态的记录跟踪方法
CN105260174B (zh) * 2015-09-16 2018-09-28 北京航空航天大学 实时Java虚拟机中基于等价类的对象内存状态的记录跟踪方法
CN105607912A (zh) * 2015-12-24 2016-05-25 华为技术服务有限公司 一种Java对象分配优化方法、装置及设备
CN105607912B (zh) * 2015-12-24 2019-07-09 华为技术服务有限公司 一种Java对象分配优化方法、装置及设备
CN108073441A (zh) * 2016-11-14 2018-05-25 阿里巴巴集团控股有限公司 一种虚拟机内存监管方法与设备
CN111274060A (zh) * 2020-02-10 2020-06-12 广州虎牙科技有限公司 一种确定内存异常的方法、装置、设备和存储介质
CN113742080A (zh) * 2020-09-10 2021-12-03 吕戈 一种高效的不可变对象执行环境的构建方法及装置
CN113742080B (zh) * 2020-09-10 2024-03-01 吕戈 一种高效的不可变对象执行环境的构建方法及装置
CN112835765A (zh) * 2021-02-02 2021-05-25 中国工商银行股份有限公司 一种Java程序内存使用情况监控方法及装置

Also Published As

Publication number Publication date
US8775769B2 (en) 2014-07-08
US20090037687A1 (en) 2009-02-05
CN101339533B (zh) 2012-10-10

Similar Documents

Publication Publication Date Title
CN101339533B (zh) 基于分区的诊断Java系统的内存泄漏的方法及装置
Xu et al. Precise memory leak detection for Java software using container profiling
Lee et al. Memfix: static analysis-based repair of memory deallocation errors for c
US7895588B2 (en) System and method for detecting and certifying memory leaks within object-oriented applications
US7912877B2 (en) Leveraging garbage collection to dynamically infer heap invariants
US7316005B2 (en) Data race detection using sequential program analysis
Wu et al. Static detection of energy defect patterns in android applications
US8645933B2 (en) Method and apparatus for detection and optimization of presumably parallel program regions
Dufour et al. A scalable technique for characterizing the usage of temporaries in framework-intensive Java applications
US8352921B2 (en) Static analysis defect detection in the presence of virtual function calls
CN100349131C (zh) 一种应用程序故障的定位方法
Hirzel et al. Pointer analysis in the presence of dynamic class loading
Seaton et al. Debugging at full speed
Ducournau Implementing statically typed object-oriented programming languages
US20090222825A1 (en) Data race detection in a concurrent processing environment
Khoo et al. Mixing type checking and symbolic execution
Qian et al. Prioritizing test cases for memory leaks in android applications
Zheng et al. Accurate profiling in the presence of dynamic compilation
Chatterjee et al. Quantitative interprocedural analysis
US7725771B2 (en) Method and system for providing enhanced memory error messages
Lencevicius et al. Dynamic query-based debugging of object-oriented programs
Li et al. Djxperf: Identifying memory inefficiencies via object-centric profiling for java
Schimmel et al. Automatic generation of parallel unit tests
Ranganath et al. Pruning interference and ready dependence for slicing concurrent java programs
CN106991042A (zh) 一种Web应用的内存泄漏定位方法

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
CF01 Termination of patent right due to non-payment of annual fee
CF01 Termination of patent right due to non-payment of annual fee

Granted publication date: 20121010

Termination date: 20200704