CN101515248A - 面向对象程序的跟踪方法和系统 - Google Patents
面向对象程序的跟踪方法和系统 Download PDFInfo
- Publication number
- CN101515248A CN101515248A CNA2008100061781A CN200810006178A CN101515248A CN 101515248 A CN101515248 A CN 101515248A CN A2008100061781 A CNA2008100061781 A CN A2008100061781A CN 200810006178 A CN200810006178 A CN 200810006178A CN 101515248 A CN101515248 A CN 101515248A
- Authority
- CN
- China
- Prior art keywords
- destination object
- code
- sign
- tracking
- computer program
- 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.)
- Pending
Links
Images
Abstract
本发明提供了一种用于面向对象程序的跟踪方法和跟踪系统,其中跟踪方法包括如下步骤:为运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码;在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识;以及在获得所述跟踪数据之后由剖析器通过基于所述通用标识建立索引来管理所述跟踪数据。
Description
技术领域
本发明涉及一种改进的数据处理系统和方法,特别地,涉及一种用于优化数据处理系统性能的方法和装置。更特别地,本发明提供一种通过软件剖析来跟踪面向对象程序的方法和系统。
背景技术
在分析和增强数据处理系统和在数据处理系统内执行的应用程序的性能中,了解在数据处理系统中哪些软件模块正在使用系统资源是有帮助的。数据处理系统的有效管理和增强需要了解不同的系统资源怎样以及何时正在被使用。性能工具被用来监控和检查数据处理系统以确定当不同的软件应用程序在数据处理系统内正在执行时的资源消耗。例如,性能工具可识别在数据处理系统中最频繁地被执行的模块和指令,或可识别那些分配最大的内存量或执行最多的I/O请求的模块。硬件性能工具可被嵌入该系统内部或及时被增加在稍后的位置。在如个人计算机系统的数据处理系统中,软件性能工具也是有用的,所述数据处理系统一般即使有也不包含许多内置的硬件性能工具。
一种已知的软件性能工具是跟踪工具。跟踪工具可使用不止一种技术来提供指示对于执行程序的执行流程的跟踪信息。一种技术通过当某些事件发生时,将其记入日志来保持对指令的特定顺序的跟踪,即所谓的基于事件的剖析技术。例如,跟踪工具可将每次进入和退出模块、子程序、方法、函数或系统组件记入日志。可替代地,跟踪工具可将请求者以及对各内存分配请求所分配的内存量记入日志。一般而言,对每个这样感兴趣的事件,产生时间戳记录。与进入-退出记录相似的相应的记录对也被用于跟踪任意代码段的执行,开始和完成I/O或数据传输,以及用于许多其它感兴趣的事件。
为了改进由不同的计算机族生成的代码的性能,经常有必要确定在执行代码时处理器在哪里花费了时间,这些努力在计算机处理领域通常被称为定位“热点地区”。理想地,为了将注意力集中在对代码来说可从改进中受益最大的区域,意欲在指令和/或代码级的源行隔离这些热点地区。
例如,对指令级隔离这些热点地区允许编译程序编制员找到次最佳的代码生成的重要的区域,在这些区域他们可集中精力改进代码生成效率。指令级细节的另一潜在的使用是对将来系统的设计者提供指导。这些设计者使用剖析工具来找到对于对给定的硬件类型的可用的软件需要优化的特征性的代码序列和/或单指令。
针对剖析进程企图捕获的信息,该系统可引起不利的影响。由于多数计算机系统是可中断的、多任务系统,因此该操作系统可以在剖析进程下,不为剖析进程所知地执行某些动作。
这些动作中最普遍的是线程切换。剖析进程企图捕获关于在特定的线程内事件发生的信息,同时该系统可执行线程切换。当该剖析进程获得用于在跟踪缓冲区内记录的理想的信息时,由于线程切换该信息可能已经改变,并且所记录的信息不能精确反映事件发生时的理想的信息。因此,提供一种用于剖析多度量的方法和系统将是有利的,并且提供线程相关的度量将是特别有利的,线程相关的度量与由线程切换引起的影响彼此隔离可使得剖析进程可记录多线程相关的度量。
还有一些跟踪工具用来实现对内存的存取跟踪。然而面向对象编程语言的运行系统的垃圾回收(GC)机制对跟踪工具提出新的挑战。
垃圾回收是一种由系统执行的自动内存管理,并企图收回由对象所用的碎片或内存,该碎片或内存将不能再次被应用程序存取或变更。在垃圾回收之后,几乎大多数垃圾回收器将压缩堆,即垃圾回收器可将有效的对象移到堆中新的位置并且移走堆中所有的空隙,且有效的对象的位置在其生命周期内可被改变几次。根据对内存存取跟踪的观察,问题在于当垃圾回收器移动对象时,对象的本地指针或地址将被无效。
然而,由于自动垃圾回收相对手动内存管理具有优势,垃圾回收免除了程序设计员处理内存分配和解除分配,所以越来越多的语言用垃圾回收特性来设计或实现。结果,消除或基本上减少了程序错误的某些分类。然而,垃圾回收使内存存取跟踪越来越难。已经有一些方法来解决或规避这个问题,这些方法包括:
使垃圾回收无效,因此内存中对象的位置不能被改变。该方法可被用于研究领域,但是在工业领域中是不实用的;
固定用户在内存中(例如在C#和LISP语言中)感兴趣的对象,因此这些被固定的对象的位置不会改变或不受垃圾回收影响。这种方法的缺点是:a)对于在内存中固定对象,垃圾回收器难于实现,b)因为被固定的对象不能被移到一起以使内存更加紧凑,所以它们导致碎片内存;
在垃圾回收之前和之后跟踪对象的地址变化(参见VIProf:Vertical integrated full system performance profiler)。本论文的作者修改垃圾回收“移动”方法以将移动的对象的源和目标地址记入日志,并且在后处理期间计算对象的地址变化。这种用于跟踪本地地址的方法具有下列缺点:a)需要记录大量的日志;b)需要更改垃圾回收例行程序;c)内存存取跟踪以后处理的方式进行,使得在线剖析是不可能的;
修改或更改Java虚拟机(JVM)。然而,针对用于跟踪本地的地址的这种方法,难于在虚拟机中更改即时(JIT)编译器;以及
其它使用参考对象或Leakbot(内存泄漏分析)的方法,这种Leakbot在空间和时间方面效率低并且具有较差的可量测性。
发明内容
考虑到现有技术存在的问题,本发明旨在提供一种新颖的跟踪技术,可以针对面向对象编程程序中的对象进行跟踪。
根据本发明的一方面,提供了一种跟踪方法,用于对运行系统中执行的由面向对象语言编程的计算机程序代码进行跟踪,所述跟踪方法包括如下步骤:为所述运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码;在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识;以及在获得所述跟踪数据之后由剖析器通过基于所述通用标识建立索引来管理所述跟踪数据。
为了实现对与目标对象相关的某部分的跟踪,本发明的跟踪方法提出了通过获取目标对象的标识(ID)以及与该目标对象相关部分的标识来组成通用标识(UniversalIdentification),利用该通用标识来管理与目标对象相关的部分的跟踪数据。例如由剖析器为各个对象的相关部分建立通用标识哈希表或其它索引,并将此后获得的跟踪数据按照通用标识进行索引以便对同一通用标识添加跟踪数据,由此可由用户可选择地实时或以后处理的方式察看针对目标对象部分的跟踪数据,例如所述剖析器可以将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至观察器。
首先由于跟踪数据是基于对计算机程序的原始代码的修改而获得的,因此运行系统在运行计算机程序的同时即获得了跟踪数据,克服了由于线程切换无法及时更新跟踪数据的缺点。其次,由目标对象的标识以及与该目标对象相关的部分的标识组成的通用标识只与目标对象本身相关,而与目标对象的实际位置无关。这样在基于本发明提出的通用标识对对象内存存取进行跟踪时则可以在独立于对象实际内存地址变化的情况下方便地获得有关内存存取的跟踪数据,因此即使在垃圾回收机制对堆空间中的目标对象进行了压缩回收的情况下仍可以准确地利用通用标识对输出的跟踪数据进行索引管理,完成对内存存取的跟踪。而如果利用本发明提出的通用标识对目标对象相关的方法进行跟踪,则跟踪数据可以直接地反映目标对象及其相关方法,因此相比利用跟踪钩子(trace hook)程序进行方法跟踪的现有技术而言可以更便利地获得用户友好的跟踪数据。
这样根据本发明,与该目标对象相关的部分可以包括与内存存取跟踪相关的目标对象的字段,或者与程序执行相关的与该目标对象相关的方法。相应地,跟踪数据除了包括以上通用标识之外,还可包括有关内存存取、其它用于确定资源消耗或其它性能、数据竞争检测或者方法调用的跟踪数据。
本发明可以着眼于收集面向对象语言编程中对象及其字段的标识。与认为程序是对计算机各种指令的列表的传统观点不同,面向对象语言编程的程序可以被认为是操作对象的集合。在面向对象语言编程中,每个对象可以接收消息,处理数据并且向其它对象发送消息。在面向对象程序中内存存取可以被认为是对对象字段的内存存取。在跟踪程序执行对运行系统的堆中的字段(变量)存取进行跟踪时,本发明获取目标对象的标识(ID)以及某字段的标识来组成通用标识,利用该通用标识来管理对象中该字段的跟踪数据。这种对象字段的标识可以利用各种已有的技术获得。优选地,在本发明中对象的字段的标识包括字段的偏移量。在各种已知的面向对象语言中可以方便地利用该编程语言中的函数、方法或类来获得各字段(或成员)的偏移量,例如在Java语言中可利用sun.misc.Unsafe类来获得。
本发明也可以着眼于对面向对象语言编程中对象及其相关方法的标识,以便监视程序在运行期间的性能和操作,跟踪程序的执行情况。
优选地,所述修改代码是在所述运行系统执行所述计算机程序之前产生的,产生步骤包括:所述运行系统加载所述计算机程序;基于所述与该目标对象相关的部分确定所述计算机程序中用于修改的代码,对所述用于修改的代码进行修改,以提供修改代码,修改代码例如包括对用于获得所述目标对象的标识以及与该目标对象相关的部分的标识的修改运行函数的调用,修改运行函数可以由单独的跟踪程序提供。可替代地,对所述代码的修改也可以采用如现有技术中已知的在所述运行系统运行所述计算机程序的原始代码的同时对原始代码补充用于获得跟踪数据的修改代码实现的,例如通过对执行引擎的编译器和/解释器进行修改来实现这种修改代码的补充。但是根据本发明优选地在所述运行系统加载所述计算机程序时完成对所述代码的修改,可以在不影响执行环境(即不修改虚拟机)的情况下以较抵的开销完成跟踪。
如果是对与对象相关的方法进行跟踪的情况下,需要修改工具将特制的代码放置在其它方法或程序可能链接的位置,例如在方法进入、方法退出、方法调用、异常抛出(throw)等等的代码。而如果在需要对对象字段的内存存取进行跟踪的情况下,修改工具会自动识别计算机程序中的存取指令(例如Java语言中的putfield和/或getfield),并在这些指令之前或之后分别放置特制的代码。这些特制的修改代码在运行系统中运行时可用来获取有关对象ID、字段或方法ID、有关该字段的存取或有关该方法的调用线程等等的跟踪数据。这样添加的修改代码不仅与原计算机程序同时得到执行,而且根本不会影响到原计算机程序的执行。
根据本发明有各种方法可获得目标对象的标识。优选地的是,通过在所述运行系统加载所述计算机程序时对加载的程序类重新定义,在利用重新定义的程序类创建对象获得所述识别目标对象的标识。其中对加载的程序类重新定义的步骤包括:为所述程序类的字段添加附加的字段;对该类的构造函数进行修改以便在创建对象时对所述附加字段赋值,得到代表所创建目标对象的标识。
根据本发明的另一方面,提供了一种跟踪系统,用于对运行系统中运行的面向对象程序进行跟踪,所述面向对象程序是由面向对象语言编程的计算机程序,所述跟踪系统包括:修改工具,被配置成为所述运行系统提供用于获得跟踪数据的与所述代码相关的修改代码;以及剖析器,被配置成在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的对象的标识以及与该对象相关的部分的标识。
优选地,所述剖析器被进一步配置成在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据,例如为跟踪数据建立哈希表索引。
优选地,所述跟踪系统还包括跟踪数据存储器和观察器,所述跟踪数据存储器存储有以通用标识作为索引的跟踪数据列表、目标对象及其相关部分的列表;所述剖析器进一步被配置成将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,利用所述对象及其相关部分的列表将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至所述观察器。
附图说明
结合附图,通过参考下列详细的示例性实施例的描述,将会更好地理解本发明本身、优选的实施方式以及本发明的目标和优点。
图1示出本发明可被实现的分布式数据处理系统;
图2示出本发明可被实现的数据处理系统的示例性框图;
图3A示出在可实现本发明的计算机系统内运行的软件组件关系的示例性框图;
图3B示出根据本发明优选实施例的Java虚拟机的示例性框图;
图4示出根据本发明一个优选实施例用于在数据处理系统中剖析进程的组件的示例性框图;
图5示出用于根据本发明一个优选实施例的方法流程图;
图6示出了根据本发明另一优选实施例对java.lang.Object类重新定义的示意图。
图7示出了根据本发明另一个实施例的通用标识列表。
图8示出了将本发明的通用标识转换成类类型和字段名的示意图。
具体实施方式
系统体系
现在参考附图,特别是图1,描述本发明可被实现的分布式数据处理系统的图形表示。分布式数据处理系统100是可实现本发明的计算机网络。分布式数据处理系统100包含网络102,网络102是用于在不同的设备和分布式数据处理系统100内连接到一起的计算机之间提供通信链接的媒介。
在所描述的例子中,服务器104与存储器106一起连接到网络102。此外,客户端108、110和112也被连接到网络102。在所描述的例子中,服务器104向客户端108、110和112提供如引导文件的数据、操作系统图像以及应用程序。分布式数据处理系统100可包括另外的服务器、客户端以及其它未显示的设备。在所描述的例子中,分布式数据处理系统100是因特网,网络102表示对使用TCP/IP协议套件来彼此通信的网络以及网关的集合。当然,分布式数据处理系统100还可被实现为不同类型的网络。
企图将图1作为例子,而不是作为本发明所述过程的结构限制。在不偏离本发明精神和范围的条件下,可对图1所示系统作出许多更改。
本发明可被实现为如图1所示的服务器104的数据处理系统。该数据处理系统可以是包括连接到系统总线的多个处理器的对称对处理器(SMP)系统。亦可使用单处理器系统。本发明还可被实现为图1中客户端计算机的数据处理系统。
现在参考图2,举例说明本发明可被实现的数据处理系统的框图。数据处理系统250是客户端计算机的例子。数据处理系统250使用外围组件互联(PCI)本地总线结构。虽然所描述的例子使用PCI总线,其它总线结构,如微通道和ISA,可被使用。处理器252和主内存254通过PCI桥258被连接到PCI本地总线256。对于处理器252,PCI桥258也可包括集成的内存控制器和高速缓存器。对PCI本地总线256的另外的连接可通过直接组件互联或通过内插板来接通。
在所描述的例子中,局域网(LAN)适配器260、SCSI主机总线适配器262以及扩展总线接口264通过直接组件连接被连接到PCI本地总线256。相比之下,音频适配器266、图形适配器268以及音频/视频适配器(A/V)269通过插入扩展槽的内插板,被连接到PCI本地总线266。扩展总线接口264为键盘和鼠标适配器270、调制解调器272以及另外的内存274提供连接。在所描述的例子中,SCSI主机总线适配器262为硬盘驱动器276、磁带驱动器278以及CD-ROM280提供连接。典型的PCI本地总线实现将支持三个或四个PCI扩展槽或内插连接器。
操作系统运行在处理器252上并被用于对在图2中的数据处理系统250内的不同组件协调和提供控制。该操作系统可以是商业上可用的操作系统。
如Java的面向对象的操作系统与该操作系统结合运行,并从Java程序或在数据处理系统250上执行的应用程序向该操作系统提供呼叫。对于该操作系统、面向对象的操作系统以及应用程序或程序的指令位于如硬盘驱动器276的存储设备,并且可被加载到主内存254用于处理器252执行。硬盘驱动器经常是缺少的且当数据处理系统250被用作网络客户端时,内存是受限的。
本领域技术人员应理解图2中的硬件可根据实现来改变。例如,如光盘驱动器等等的其它的外围设备可被另外或在图2所描述的硬件的位置使用。所描述的例子并不意味对本发明暗含结构限制。例如,本发明的方法可被应用于多处理器数据处理系统。
JVM运行系统
本发明提供一种用于剖析(例如跟踪)软件应用程序的方法和系统。本发明可运行在Java运行环境内,但也可运行在多种计算机平台和操作系统上。因此,本发明尽管是在被Java标准规范定义的Java虚拟机(JVM)的范围内结合JVM来运行,但是JVM也可以是任何类型的独立于平台的虚拟机,如C#、Smalltalk、Ruby、D语言、nuva,而不限于Java虚拟机。为了对本发明提供上下文,这里描述了根据Java规范的JVM操作的部分。
现在参考图3A,提供了举例说明在可实现本发明的计算机系统内运行的软件组件的关系的框图。基于Java的系统300包含专用平台操作系统302,该操作系统302向在专用硬件平台上执行的软件提供硬件和系统支持。JVM304是一种可结合操作系统执行的软件应用程序。JVM304提供有能力执行Java应用程序或小应用程序306的Java运行环境,Java应用程序或小应用程序306是以Java编程语言编写的程序、小服务程序或软件组件。JVM304运行的计算机系统可以与上述数据处理系统250或100相似。然而,JVM304也可在所谓的Java芯片、硅上Java或具有嵌入的picoJava核的Java处理器上的专用硬件中被实现。
Java运行环境的中心是JVM,JVM支持Java环境的所有方面,包括其结构、安全特性、跨网络移动以及平台独立。
JVM是虚拟计算机,即被抽象说明的计算机。就可取决于JVM被设计执行的平台的设计选择的某范围,规范定义了每个JVM必须实现的某些特征。例如,所有的JVM必须执行Java字节码并可使用各种技术以执行由字节码所表示的指令。可以以软件或以软硬件结合方式来完全实现JVM。这种灵活性允许为大型计算机和PDA来设计不同的JVM。
JVM是实际上执行Java代码的虚拟计算机组件的名称。Java程序不是直接由中央处理器而是由JVM替代来运行,JVM本身是一个运行在处理器上的软件。与仅仅借助一个平台编译程序的方法相反,JVM允许Java程序在不同的平台上被执行。Java程序被JVM编译。以这种方式,Java能支持用于可包含多种中央处理单元和操作系统结构的多种类型的数据处理系统的应用程序。为了使Java应用程序能在不同类型的数据处理系统上执行,编译器一般生成结构中立的文件格式,如果存在Java运行环境,被编译的代码可在多种处理器上执行。Java编译器生成非专用于特定的计算机结构的字节码指令。字节码是由Java编译器生成的独立于机器的代码并被Java解释器执行。代码解释器是交替译码和解释一个字节码或多个字节码的JVM的部分。这些字节码指令被设计为在任何计算机上容易解释并在线容易被翻译成本地机器代码。字节码可被即时(JIT)编译器或JIT翻译成本地代码。
JVM必须加载类文件并在类文件内执行字节码。该JVM包含类加载器,该类加载器从应用程序中加载类文件,并从应用程序所需要的Java应用编程接口(APIs)中加载类文件。对于不同的平台和实现执行字节码的执行引擎不尽相同。
一种基于软件的执行引擎是即时编译器。就这种执行而言,基于成功实现用于JITting(即时编译)方法的某种标准,方法的字节码被编译成本地机器代码。然后,对于这种方法的本地机器代码被高速缓存并在下次调用该方法时被重新使用。该执行引擎还可在硬件中被实现并被嵌在芯片上使得Java字节码在本地被执行。JVM通常解释字节码,但是JVM还可使用如即时编译器的其它技术来执行字节码。
解释代码提供了另外的好处。作为修改Java源代码的替代,该解释器可被修改。在不修改源代码的条件下,通过修改的解释器,经选择的事件和定时器,跟踪数据可被生成。在下面将更加详细地讨论剖析修改。
当应用程序在专用平台操作系统上以软件实现的JVM上执行时,Java应用程序可通过调用本地方法与主机操作系统互动。Java方法以Java语言编写、编译成字节码并存储在类文件中。本地方法以某种其它语言编写并编译成特定处理器的本地机器代码。本地方法被存储在动态链接库中,该链接库的确切格式是平台专用的。
现在参考图3B,根据本发明优选实施例示出JVM的框图。JVM350包括类加载器子系统352,该类加载器子系统352是用于加载给定完全合格的名称的类型,如类和接口的装置。JVM350还包括运行数据区354、执行引擎356和本地方法接口358。执行引擎356是用于执行包含在由类加载器子系统352加载的类的方法中的指令的装置。执行引擎356可以例如是Java解释器362或即时编译器360。本地方法接口358允许存取操作系统的潜在资源。本地方法接口358可以例如是Java本地接口。
对于各个执行方法,在执行引擎356中存在相应的Java帧和操作数栈。JVM是基于栈的机器,所以操作数栈是JVM指令在其上运行的位置。Java帧包含不同的指针。存在指向方法区370内部的指针以指示当前的执行方法和其指令。并且存在指向垃圾回收的堆372内部的指针以指示正在执行方法的本地变量。
运行数据区354包含本地方法栈364、Java栈366、PC寄存器368、方法区370以及堆372。这些不同的数据区代表JVM350以执行程序所需要的内存的结构。
Java栈366用于存储Java方法调用的状态。当新的线程运行时,JVM为该线程创建新的Java栈。该JVM直接在Java栈上仅仅执行两个操作:JVM对帧进行压栈和出栈。线程的Java栈存储对该线程Java方法调用的状态。Java方法调用的状态包括它的本地变量、它被调用的参数、它的返回值、以及(如果有)中间的计算。Java栈包括栈帧。栈帧包含单个Java方法调用的状态。当线程调用方法时,JVM将新的帧压到该线程的栈中。当该方法完成时,JVM使与那个方法相关的帧出栈并丢掉该帧。JVM没有任何用于保存中间值的寄存器;并且任何需要或产生中间值的Java指令使用栈来保存中间值。以这种方式,用于多种平台结构的Java指令集是明确的。
PC寄存器368被用于指示下一个将被执行的指令。各个例示的线程得到其本身的程序计数器(pc)寄存器和Java栈。如果该线程正在执行JVM方法,pc寄存器的值指示要执行的下一指令。如果该线程正在执行本地方法,该pc寄存器的内容是不明确的。
本地方法栈364存储本地方法调用的状态。本地方法调用的状态以基于实现的方式被存储在本地方法栈、寄存器或其它基于实现的内存区中。在一些JVM实现中,本地方法栈364和Java栈366被合并。
方法区370包含类数据,而堆372包含所有例示的对象。JVM规范严格定义了数据类型和操作。多数JVM选择具有一个方法区和一个堆,各个方法区和堆被在JVM内运行的所有的线程分享。当JVM加载类文件时,该JVM从包含在类文件中的二进制数据中解析关于类型的信息。JVM将这种类型信息放置到方法区内。当类实例或队列被创建时,对于该新的对象的内存被从堆372中分配。JVM350包括指令,该指令在内存内分配用于堆372的内存空间,但是不包括用于在内存中释放那块空间的指令。在所描述的例子中,内存管理374管理分配给堆370的内存内的空间。内存管理374可包括自动收回不再被涉及的对象所用的内存(堆)的垃圾回收器。另外,垃圾回收器可移动对象以减少堆碎片。
跟踪系统:
本发明的跟踪系统用于对运行系统中执行的由面向对象语言编程的计算机程序代码进行跟踪,所述跟踪系统包括:修改工具,被配置成为所述运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码,和剖析器,被配置成在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的对象的标识以及与该对象相关的部分的标识,所述剖析器被进一步配置成在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据。
现在参考图4,框图描述了根据本发明的优选实施例在数据处理系统中用于剖析进程的组件。跟踪系统400用于对运行系统中执行的由面向对象语言编程的计算机程序(例如程序类)代码进行跟踪,包括:修改工具401,被配置成为JVM450提供与原始代码相关的修改代码;和剖析器402,被配置成在JVM450的执行引擎456执行包括所述修改代码在内的所述计算机程序代码时,从所述运行系统获得跟踪数据并可以对该跟踪数据进行剖析,所述跟踪数据至少包括包含所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识的通用标识,所述剖析器被进一步配置成在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据,例如基于所述通用标识为跟踪数据建立哈希表索引。根据本发明的优选实施例,修改工具401可以在类加载器452(例如图3B所示的类加载器子系统352)加载程序类时在该程序类的特定位置添加用于获得跟踪数据的与所述代码相关的修改代码。但可替代地修改工具401也可以对执行引擎456进行修改。当JVM450的执行引擎456与运行数据区454交互数据以便执行修改代码时,产生跟踪数据以向跟踪系统400发送,跟踪系统400的剖析器402用于记录数据,在剖析器402的缓存器中存储跟踪数据。
根据另一变型方式,跟踪系统400还包括跟踪数据存储器404和观察器403。剖析器402的缓存器中的跟踪数据可随后被存储在跟踪数据存储器404中作为后处理的文件,或者该跟踪数据可以被实时处理,发送给观察器403。所述剖析器进一步被配置成将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,利用所述目标对象及其相关部分的列表将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至所述观察器。
根据本发明,当应用程序执行时,为了获得关于当前的运行环境的信息,该应用程序不需要被周期性中断。这个信息可被写到缓存器或用于后处理的文件,或者该信息可被在线处理成表示正在进行的运行环境的历史的数据结构。
跟踪方法:
本发明的跟踪方法用于对运行系统中执行的由面向对象语言编程的计算机程序代码进行跟踪,所述跟踪方法包括如下步骤:为所述运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码;在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识;以及在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据。
在获得所述跟踪数据之后可以将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至观察器。
所述修改代码是在所述运行系统执行所述计算机程序代码的同时通过对原始代码补充用于获得跟踪数据的修改代码而产生的。或者,所述修改代码是在所述运行系统执行所述计算机程序代码之前产生的,所述修改代码的产生包括以下步骤:所述运行系统加载所述计算机程序;基于所述与该目标对象相关部分确定所述计算机程序中用于修改的代码;和对所述用于修改的代码进行修改,以提供修改代码。
其中,对所述用于修改的代码进行修改的步骤包括:添加对用于获得所述目标对象的标识以及与该目标对象相关的部分的标识的修改运行函数的调用,所述修改运行函数是由单独的跟踪程序提供的。
图5示出用于根据本发明一个优选实施例的方法流程图,其中跟踪系统的修改工具在加载计算机程序时即对其代码进行修改。该方法500在步骤S501开始后,在步骤S502运行系统加载计算机程序,跟踪系统的修改工具扫描计算机程序的代码(步骤S503),并确定用于修改的代码(步骤S504)进行修改(步骤S505),随后运行系统JVM经由运行数据区获得原始代码和修改代码后执行这些代码(步骤S506),修改代码用于执行跟踪,特别是根据本发明会获取包括由计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识组成的通用标识。在步骤S507,修改代码将获得包括通用标识的跟踪数据。在步骤S508判断跟踪是否结束,并在步骤S509完成。
根据其它变型方案,修改工具还可以在运行系统的执行引擎进行编译时进行修改。同时优选地修改工具在执行修改以添加用于获得跟踪数据的与所述代码相关的修改代码的同时,也可以对计算机程序中涉及的类进行重新定义,以便在利用重新定义的程序类创建对象时获得所述识别目标对象的标识。对加载的程序类重新定义的步骤可以包括:为所述程序类的字段添加附加的字段;对该类的构造函数进行修改以便在创建目标对象时对所述附加字段赋值,得到代表所创建目标对象的标识。
所述与该目标对象相关的部分可包括目标对象的字段,或者与该目标对象相关的方法。
第一实施例:针对对象的内存存取跟踪
为了实现对内存中对象中某部分的存取跟踪,本发明的跟踪程序提出了通过获取目标对象的标识(ID)以及该部分的标识来组成通用标识,利用该通用标识来管理对象中该部分的跟踪数据。这样由于采用了独立于对象实际内存地址变化的通用标识,本发明的跟踪程序可以在不影响执行环境(即虚拟机)的情况下以较抵的开销完成内存存取跟踪。
例如如果跟踪程序执行对堆(heap)中变量(字段)的存取的跟踪,本发明获取目标对象的标识(ID)以及某字段的标识来组成通用标识,利用该通用标识来管理对象中该字段的跟踪数据。
有关每个对象的ID(标识),根据现有技术各种面向对象的编程语言已经公开了各种为对象提供ID的技术手段(例如US7246141公开通过编码偏斜值“skew value”获得对象的ID),本发明可以对其进行利用。另外本发明也提出了对每个对象添加ID。以下以java.lang.Object类为例说明如何对每个对象添加ID。
在运行Java程序时,包含主程序的类首先通过类加载器子系统352被加载到JVM中。同时JVM也加载跟踪设备中的跟踪程序。
图6示出了根据本发明另一优选实施例对java.lang.Object类重新定义的示意图。修改工具(instrumentation facility)在程序类被加载到类加载器之时利用字节代码(在Java语言下是字节代码,但本发明并不限于字节代码)修改对原始的java.lang.Object类601的字段611添加附加的字段612如int字段(例如该字段加载到堆中的所有字段之后或其它特定位置,在java中int赋予的是32位),以便在赋值后产生对象的ID例如objectId;同时对该类的java.lang.Object<init>构造函数621进行修改,对java.lang.Object<init>构造函数所添加的代码622在利用重新定义的java.lang.Object类620创建对象时对int字段612赋值分配特定的整数,该特定的整数相对于各个对象是唯一的,即代表了所创建对象的ID。本领域普通技术人员可以想象到各种在执行时分配特定整数的工具。
在跟踪程序初始化后,修改工具除了如上所述对类重新定义之外,还需要在计算机程序的特定位置插入特制的代码,以便在执行该修改代码时跟踪程序记录数据,对计算机程序进行剖析(profile),例如数据获取、调试、性能分析或者功能增强。众所周知,跟踪程序在初始化阶段可以捕获用来识别所有现有线程、所有加载类及其方法的跟踪初始数据。借此,如果是对对象的相关方法进行跟踪的情况下,修改工具需要将特制的代码放置在其它程序可能连接的位置。而如果在需要对对象字段的内存存取进行跟踪的情况下,修改工具会自动识别计算机程序中的例如putfield和/或getfield等存取指令,并在这些指令之前分别放置特制的代码。这些特制的修改代码在运行系统中运行时可用来获取有关对象ID、字段或方法ID、有关该字段的存取或有关该方法的调用线程等等跟踪数据,并可将这些跟踪数据发送到跟踪设备,该跟踪设备将这些跟踪数据存储在缓存器中,这些跟踪数据可以由剖析器随后存储在进程后的文件中,或者也可以被实时处理。在这种情况下任何加载的感兴趣的类具有跟踪记录,表明类(或对象)名及其方法的跟踪记录。在本实施例中用4个字节的ID来作为线程、类(或对象)以及方法的标识。
根据本发明,跟踪数据包括通用标识。以下以对象foo的字段i为例说明利用本发明对该字段i的内存存取跟踪。
代码插入:
针对如下对类MyObject进行定义并赋值的计算机程序,通常JVM会相应地执行aload_1(将临时变量加载到栈顶)、iconst_1(将整数型常数1加载到栈顶)以及putfield(写操作)的指令操作。
class MyObject{int i;}MyObject foo=new MyObject();foo.i=1; |
aload_1iconst_1putfield |
在利用本发明的情况下,首先修改工具在类文件被加载到类加载器子系统352时利用字节代码修改对该java.lang.Object类添加int字段并对该类的java.lang.Object<init>构造函数进行修改,以便随后在创建对象时对int字段赋值,得到唯一的ID(各对象的ID),如图6所示。
之后,修改工具对计算机程序自动解析发现了计算机程序中存在对对象字段的存取操作指令(如putfield或getfield,在此为putfield),则在该指令前添加与如下程序中所执行的代码2-8相对应的字节代码。在此假定跟踪程序中的Runtime类所在的包为com/ibm/xtools/threadanalysis/util。
1:aload_1//将临时变量1加载到栈顶2:iconst_1//将整数型常数1加载到栈顶3:swap //交换栈顶的两个元素4:dup_x1 //跨越栈顶第二个元素,拷贝栈顶元素5:getstaticcom/ibm/xtools/threadanalysis/util/Runtime.runtime:Lcom/ibm/xtools/threadanalysis/util/Runtime;//将跟踪程序中的Runtime类的静态变量Runtime.runtime加载到栈顶6:swap//交换栈顶的两个元素7:ldc //把fieldID作为常数加载到栈顶8:invokevirtualcom/ibm/xtools/threadanalysis/util/Runtime.putField:(Ljava/lang/Object;I)V//调用跟踪程序中的Runtime类的putField方法9:putfield//执行putfield指令(不同于以上putField方法) |
以上添加的代码需要分别在代码(步骤)5和8中加载和调用跟踪程序中的静态变量Runtime.runtime和putField方法(即修改运行函数)。
跟踪程序:
在跟踪设备中配置的跟踪程序定义了以上需要的静态变量Runtime.runtime和putField方法,具体如下表示:
Class Runtime{public static Runtime runtime;putField(Object obj,int fieldID){long ua=obj.objectId;ua=ua<<32;ua=ua|fieldID;//UA is collect here ......}getField(Obj ect obj,int fieldID){long ua=obj.objectId;ua=ua<<32;ua=ua|fieldID;//UA is collect here ......}} |
在上述定义中静态变量Runtime runtime用于与filed ID、对象ID一起组成跟踪数据。
putField方法具有两个参数:Object obj,int fieldID,在本实施例中fieldID的数据类型可选择为32位(int);
obj.objectId的数据类型用32位表示,objectId的实际数值占据低位,例如低32位(long ua=obj.objectId);
将fieldID添加到objectId结尾,组成变量ua;实际执行时将原objectId的实际数值左移32位,占据obj.objectId的高32位,同时将fieldID32位添加到objectId的后面(ua=ua<<32;ua=ua|fieldID);
由此收集了通用标识(//UA is collect here)。以对象foo的字段i为例,UniversalIdentification(foo.i)=<ID of foo,ID of i infoo>,即UniversalIdentification(foo.i)=foo.objectId<<32+IDof i(i,foo)。
getField方法与putField方法类似,不同的是这两个方法针对不同的读写指令,getField方法是在计算机程序中对对象的某字段进行读操作的指令(如getfield指令)之前调用的,而putField方法是在对对象的某字段进行写操作的指令(如putfield指令)之前调用的。
在以上跟踪程序的定义中,利用Java的固有数据类型分别将obj.objectId和fieldId表示为32位和32位,但是可以设想到使用其它编程语言和/或其它的数据类型来表示obj.objectId和fieldId,只要将fieldID添加到objectId末尾组成通用标识即可,而不局限于obj.objectId和fieldId分别为32位和32位。
JVM运行修改后的计算机程序:
在上述经修改之后的类文件由JVM加载、验证和解析后,再由JVM的执行引擎执行。在执行上述修改代码的过程中JVM的栈变化情况如下表1所示。
表1
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
foo | 1 | foo | foo | runtime | foo | fieldID | 1 | |
foo | 1 | 1 | foo | runtime | foo | foo | ||
foo | 1 | 1 | runtime | |||||
foo | foo | 1 | ||||||
foo |
表1中横向数字1-9表示JVM执行引擎随时间所执行的相应代码(即步骤)的编号,每个数字下方表示相应的JVM栈内变化情况。例如:
步骤1按照原计算机程序的指令将临时对象foo加载到栈顶;
在执行步骤2中按照原计算机程序的指令,整数型常数1后进;
步骤3-8由修改工具添加到原计算机程序中,此时由JVM的执行引擎执行。在步骤3交换栈顶的两个元素之后,步骤4拷贝当前栈顶的第二个元素(对象foo);
此时步骤5开始将跟踪程序中的Runtime类的静态变量Runtime.runtime加载到栈顶;
步骤6交换栈顶的两个元素:静态变量runtime和对象foo;
步骤7将field ID作为常数加载到栈顶,在此field ID可以根据Java规范对putfield指令之后的数值经过转换来确定;
步骤8调用跟踪程序中的Runtime类的putField方法(即修改运行函数),参考对跟踪程序中putField方法的描述,执行putField方法获得包括静态变量、对象foo和fieldID,借助对象foo从堆中获得对象foo的ID,将该对象foo的ID以及fieldID组成通用标识,发送到跟踪设备的剖析器(或者剖析器的缓存器);
步骤9继续执行原计算机程序的putfield指令,将1和foo写入到堆中该对象的相应字段。
应该了解,对于本领域的普通技术人员而言按照JVM栈后进先出的规则也可以调节步骤3-8(例如交换栈顶的两个元素,拷贝栈顶元素)的顺序,甚至整个修改的代码插入在原计算机程序的putfield指令之后,只要最终能获得包含通用标识在内的跟踪数据即可。
跟踪数据管理:
在跟踪设备的剖析器获得通用标识以及其它跟踪数据后,利用通用标识列表进行管理。可以在第一次获得通用标识时在剖析器(或者剖析器的缓存器)中创建通用标识列表并为该列表添加所获得的跟踪数据。图7示出了根据本发明一个实施例的通用标识列表700。剖析器可以针对每个对象字段创建基于通用标识的列表,其中通用标识列表中的每一个槽(slot)701都带着一个链表,链表上记录着所有对这个通用标识上的存取信息。例如,链表上的每一个元素702记录着针对该通用标识的内存访问类型(读或写)、访问内存的线程ID、以及该线程进行内存操作的时候获得的锁集合,用于数据竞争检测,有关数据竞争检测将在下文详细描述。当然也可以根据需要通过代码修改来获取其它的用于确定资源消耗或其它性能、甚至方法调用的跟踪数据。
而在此之后获得通用标识以及其它跟踪数据,剖析器会利用该哈希(hash)表索引为列表中已存在的通用标识顺序添加跟踪数据,而对第一次获得的通用标识(即表示新的对象字段)创建针对该通用标识的slot和链表。还可以设想到除哈希(hash)表之外的如B-tree等其它方法为通用标识及其跟踪数据建立索引。
根据上述本发明的实施例,链表上的每一个元素702记录的跟踪数据包括针对该通用标识的内存访问类型(读或写)、访问内存的线程ID、以及该线程进行内存操作的时候获得的锁集合。当然本发明也可以根据需要跟踪程序或方法执行过程中的其它数据,这一点可以通过修改插入在计算机程序中的相应代码来实现,并且本领域的普通技术人员可以轻易地实现。总之,只要采用了通用标识,本发明的跟踪技术即可在独立于对象实际内存地址变化的情况下进行,不影响执行环境(即无需修改虚拟机)并且以较抵的开销完成内存存取跟踪。
实时处理跟踪信息或后处理阶段创建报告:
由于由执行引擎一体执行原始代码和修改代码,因此本发明可以实现实时(on-the-fly)地处理跟踪信息,这样可以在剖析期间维持跟踪数据结构。换句话说,在对缓存器或记录文件写入跟踪记录以外的时间执行剖析函数时或者是在写入跟踪记录和执行剖析函数的同时,处理跟踪记录信息以便构建和维持任何合适的数据结构。有时需要判断是否发生了终止条件。如果发生了终止条件(例如中断了跟踪),则停止操作。否则继续对程序的剖析和剖析后操作以产生跟踪数据结构。或者,在后处理阶段,通用标识列表还可用来创建报告以进行分析。
在使用跟踪数据时,例如当发现程序中出现数据竞争的问题时,需要把通用标识翻译成用户可以理解的信息。如图8所示,跟踪数据存储器中存储有对象列表(objects list)801以及类信息数组(class informationarray)802,对象列表801记载了对象标识所代表的对象对应的类类型,类信息数组802记载了各类型类中字段的名称,如附图标记8021所代表的类型A下有名称为f1、f2、f3和f4的字段,附图标记8022所代表的类型C下有名称为a1、a2和a3的字段。
以下简要描述翻译通用标识产生跟踪报告的过程。首先,剖析器将通用标识分解成对象ID(对象标识)和字段ID(字段标识);然后,在对象列表801中通过对象ID查询这个对象对应的类型是A类型或其它的类型;得到这个对象的类型后,根据字段标识(例如字段偏移量)在类信息数组802中再次确定在这个类型类中这个字段803的名称是什么。比如可以创建竞争检测报告,one race happens on object 12345,type Class A, field f2(在目标12345,类A类型,字段f2)。
基于以上描述,借助本发明,在程序运行时无需为获得当前运行环境的信息间隙性中断应用程序。这种信息可以写到缓存器或后处理文件中,或者该信息可以实时处理为表示运行环境历史数据的数据结构。
对象ID的变型:
另外在以上的描述中,字段的标识(field ID)与目标对象的标识(Object ID)一起构成通用标识。在现有技术中同样存在很多的方式来获得字段的标识,本发明可以采用任何一种。优选的,本发明以字段i在该对象中的偏移量(offset相对位置)作为该字段的ID,因为这种偏移量本质上就是用于区别各个字段的独特特征。在Java语言中,考虑到类sun.misc.Unsafe即有一个ObjectFieldOffset的方法,则可直接利用sun.misc.Unsafe来得到field offset。
import sun.misc.Unsafe;
import java.lang.reflect.*;
Unsafe unsafe=Unsafe.getUnsafe();
Field f=foo.getClass().getDeclairedField(“i”);
long offset=unsafe.ObjectFieldOffset(f)
这样获得的通用标识(Universal Identification)即由下式表示(在此同样以foo.objectId和fieldoffset为32位和32位数据类型为例):
Universal Identification(foo.i)=<ID of foo,offset of i infoo>,
i.e.Universal Identification(foo.i)=foo.objectId<<32+fieldoffset(i,foo)。
数据竞争检测
除了监控和检查数据处理系统以确定资源消耗或其它性能,本发明也可用于数据竞争检测。
在多线程程序中,当两个线程在没有施加在存取之间的顺序约束的条件下存取同一内存位置时,数据竞争发生,使得至少存取之一是写。在多种情况下,数据竞争是编程错误。并且,众所周知具有数据竞争的程序难于调试,因为当用同样的输入组重复执行时,它们呈现不同的行为。然而,对于数据竞争检测,为了之后的分析,需要记录每次内存存取的位置和其它信息。然而,如果同一对象被垃圾回收器移动时,同一对象的位置被改变,并且之后的分析不能正确运行。
如上所述,跟踪设备的剖析器获得通用标识以及其它跟踪数据,在针对数据竞争进行跟踪的情况下,这些其它的跟踪数据可包括针对该通用标识的内存访问类型(读或写)、访问内存的线程ID、以及该线程进行内存操作的时候获得的锁集合。其实现方式是:通过在修改代码所调用的运行修改函数中(例如“代码插入”部分中的putField方法中,具体可以是在收集通用标识的代码之后)添加对“有关该字段的存取状态、线程的标识及线程获得的锁集合的跟踪数据”的获取,即可由剖析器获得这些用于数据竞争检测的特定跟踪数据。
借助通用标识列表中记录的对线程及其操作时获得的锁集合即可对线程是否存在竞争进行判断,并可根据现有技术忽略准备执行操作的并被判断为是冗余的线程,而不影响对由该通用标识表示的位置的竞争检测。同理,由于采用独立于对象实际内存地址变化的通用标识,本发明可以在不影响执行环境(即虚拟机)的情况下以较抵的开销完成竞争检测。
第二实施例:针对与对象相关方法的跟踪
如上所述,如果是对与对象相关的方法进行跟踪的情况下,修改工具需要确定计算机程序中与方法进入、方法退出、方法调用或异常抛出相对应的代码,对这些代码添加特制的代码(即将这些特制的代码放置在其它程序可能连接的位置),所述特制的代码包括对用于获得所述目标对象的标识以及所述与对象相关的方法的标识的修改运行函数的调用。这些特制的修改代码在运行系统中运行时可用来获取有关对象ID、方法ID、有关该方法的调用线程等等跟踪数据,并可将这些跟踪数据发送到跟踪设备,该跟踪设备将这些跟踪数据存储在缓存器中,这些跟踪数据可以由剖析器随后存储在进程后的文件中,或者也可以被实时处理。在这种情况下任何加载的感兴趣的类都具有跟踪记录,表明类(或对象)名及其方法的跟踪记录。在本实施例中分别用4个字节的ID来作为线程、类(或对象)以及方法的标识。
其它实施例
本发明中的运行系统VM可以是任何类型的独立于平台的虚拟机,如C#、Smalltalk、Ruby、D语言、nuva,而不限于Java虚拟机。可以了解在所有的面向对象的语言中对象包括数据(字段)和操作数据的方法,因此在本发明中“与对象相关的部分”包括对象的字段或者与对象相关的方法。
在本发明以上的实施例中,通用标识均由所述计算机程序所创建的对象的标识以及与该对象相关的部分的标识组成,但可以设想,如果希望对对象某字段在某个函数中的所有读写进行跟踪,则可利用对象的标识、该字段的标识以及相关方法的标识共同组成通用标识,同理如果在对对象某字段在某个类中的所有读写进行跟踪的情况下,可利用所述对象的标识、所述字段的标识以及所述类的标识共同组成通用标识,利用这种通用标识管理跟踪数据,同样可获得以上相同的有益技术效果。综上,本发明的通用标识应被理解为至少包括所述计算机程序所创建的对象的标识以及与该对象相关的部分的标识。
另外,对本领域的普通技术人员而言,能够理解本发明的方法和装置的全部或者任何步骤或者部件,可以在任何计算设备(包括处理器、存储介质等)或者计算设备的网络中,以硬件、固件、软件或者它们的组合加以实现,这是本领域普通技术人员在阅读了本发明的说明的情况下运用他们的基本编程技能就能实现的,因此在这里省略了详细说明。
因此,基于上述理解,本发明的目的还可以通过在任何信息处理设备上运行一个程序或者一组程序来实现。所述信息处理设备可以是公知的通用设备。因此,本发明的目的也可以仅仅通过提供包含实现所述方法或者设备的程序代码的程序产品来实现。也就是说,这样的程序产品也构成本发明,并且存储有这样的程序产品的存储介质也构成本发明。显然,所述存储介质可以是任何公知的存储介质或者将来所开发出来的任何存储介质,因此也没有必要在此对各种存储介质一一列举。
在本发明的设备和方法中,显然,各部件或各步骤是可以分解和/或重新组合的。这些分解和/或重新组合应视为本发明的等效方案。
以上描述了本发明的优选实施方式。本领域的普通技术人员知道,本发明的保护范围不限于这里所公开的具体细节,而可以具有在本发明的精神实质范围内的各种变化和等效方案。
Claims (29)
1.一种跟踪方法,用于对运行系统中执行的由面向对象语言编程的计算机程序代码进行跟踪,所述跟踪方法包括如下步骤:
为所述运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码;
在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识;以及
在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据。
2.根据权利要求1所述的跟踪方法,其中还包括:基于所述通用标识为跟踪数据建立哈希表索引。
3.根据权利要求1所述的跟踪方法,其中还包括:在获得所述跟踪数据之后将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至观察器。
4.根据权利要求1所述的跟踪方法,其中所述修改代码是在所述运行系统执行所述计算机程序代码的同时通过对原始代码补充用于获得跟踪数据的修改代码而产生的。
5.根据权利要求1所述的跟踪方法,其中所述修改代码是在所述运行系统执行所述计算机程序代码之前产生的,所述修改代码的产生包括以下步骤:
所述运行系统加载所述计算机程序;
基于所述与该目标对象相关的部分确定所述计算机程序中用于修改的代码;和
对所述用于修改的代码进行修改,以提供修改代码。
6.根据权利要求5所述的跟踪方法,其中对所述用于修改的代码进行修改的步骤包括:添加对用于获得所述目标对象的标识以及与该目标对象相关的部分的标识的修改运行函数的调用。
7.根据权利要求6所述的跟踪方法,其中,所述修改运行函数是由单独的跟踪程序提供的。
8.根据权利要求1所述的跟踪方法,其中所述与该目标对象相关的部分包括目标对象的字段,或者与该目标对象相关的方法。
9.根据权利要求1所述的跟踪方法,其中所述与该目标对象相关的部分是目标对象的字段,所述目标对象字段的标识是该字段的偏移量。
10.根据权利要求5所述的跟踪方法,其中所述与该目标对象相关的部分是目标对象的字段,
所述确定用于修改的代码的步骤包括:确定所述计算机程序中与所述目标对象字段的存取指令相对应的代码,
对所述用于修改的代码进行修改的步骤包括:添加对用于获得所述目标对象的标识以及所述目标对象字段的标识的修改运行函数的调用。
11.根据权利要求10所述的跟踪方法,其中,所述修改运行函数还用来获得包括有关该字段的存取状态、线程的标识及线程获得的锁集合的跟踪数据。
12.根据权利要求10所述的跟踪方法,其中,对所述用于修改的代码进行修改的步骤还包括:添加用于在所述运行系统运行时从所述运行系统获得所述目标对象的标识以及所述目标对象字段的标识的指令。
13.根据权利要求5所述的跟踪方法,其中所述与该目标对象相关的部分是与所述目标对象相关的方法,
所述确定用于修改的代码的步骤包括:确定所述计算机程序中与方法进入、方法退出、方法调用或异常抛出相对应的代码,
对所述用于修改的代码进行修改的步骤包括:添加对用于获得所述目标对象的标识以及所述与目标对象相关的方法的标识的修改运行函数的调用。
14.根据权利要求1所述的跟踪方法,其中所述运行系统加载所述计算机程序时对加载的程序类重新定义,以便在利用重新定义的程序类创建目标对象时获得所述识别目标对象的对象标识。
15.根据权利要求14所述的跟踪方法,其中对加载的程序类重新定义的步骤包括:为所述程序类的字段添加附加的字段;对该类的构造函数进行修改以便在创建目标对象时对所述附加字段赋值,得到代表所创建目标对象的标识。
16.一种跟踪系统,用于对运行系统中执行的由面向对象语言编程的计算机程序代码进行跟踪,所述跟踪系统包括:
修改工具,被配置成为所述运行系统提供用于获得跟踪数据的与所述计算机程序代码相关的修改代码,和
剖析器,被配置成在所述运行系统执行包括所述修改代码在内的所述计算机程序的代码时,从所述运行系统获得跟踪数据,所述跟踪数据至少包括通用标识,所述通用标识包括所述计算机程序所创建的目标对象的标识以及与该目标对象相关的部分的标识,
所述剖析器被进一步配置成在获得所述跟踪数据之后通过基于所述通用标识建立索引来管理所述跟踪数据。
17.根据权利要求16所述的跟踪系统,其中所述剖析器基于所述通用标识为跟踪数据建立哈希表索引。
18.根据权利要求16所述的跟踪系统,其中所述跟踪系统还包括跟踪数据存储器和观察器,所述跟踪数据存储器存储有以通用标识作为索引的跟踪数据列表、目标对象及其相关部分的列表;
所述剖析器进一步被配置成将所述通用标识分解成目标对象的标识和目标对象相关部分的标识,利用所述目标对象及其相关部分的列表将目标对象的标识和目标对象相关部分的标识转换为类类型和目标对象相关部分的名称,以实时或事后的方式产生跟踪报告并将所述跟踪报告发送至所述观察器。
19.根据权利要求16所述的跟踪系统,其中所述修改工具被配置成:在所述运行系统加载所述计算机程序时,基于所述与该目标对象相关的部分确定所述计算机程序中用于修改的代码;以及对所述用于修改的代码进行修改,以提供修改代码。
20.根据权利要求19所述的跟踪系统,其中所述修改工具被进一步配置成:为所述用于修改的代码添加对用于获得所述目标对象的标识以及与该目标对象相关的部分的标识的修改运行函数的调用。
21.根据权利要求20所述的跟踪系统,其中,所述跟踪系统根据所述运行系统执行所述计算机程序的代码时对所述修改运行函数的调用提供所述修改运行函数。
22.根据权利要求16所述的跟踪系统,其中所述与该目标对象相关的部分包括目标对象的字段,或者与该目标对象相关的方法。
23.根据权利要求16所述的跟踪系统,其中所述与该目标对象相关的部分是目标对象的字段,所述目标对象字段的标识是该字段的偏移量。
24.根据权利要求19所述的跟踪系统,其中所述与该目标对象相关的部分是目标对象的字段,
所述修改工具被进一步配置成:确定所述计算机程序中与对所述目标对象字段的存取指令相对应的代码;以及添加对用于获得所述目标对象的标识以及所述目标对象字段的标识的修改运行函数的调用。
25.根据权利要求24所述的跟踪系统,其中,所述修改运行函数还用来获得包括有关该字段的存取状态、线程的标识及线程获得的锁集合的跟踪数据。
26.根据权利要求24所述的跟踪系统,其中,所述修改工具被进一步配置成:添加用于在被运行时从所述运行系统获得所述目标对象以及所述目标对象字段的标识的指令。
27.根据权利要求19所述的跟踪系统,其中所述与该目标对象相关的部分是与目标对象相关的方法,
所述修改工具被进一步配置成:确定所述计算机程序中与方法进入、方法退出、方法调用或异常抛出相对应的代码,以及为所确定的代码添加对用于获得所述目标对象的标识以及所述与目标对象相关的方法的标识的修改运行函数的调用。
28.根据权利要求16所述的跟踪系统,其中所述修改工具被进一步配置成:在所述运行系统加载所述计算机程序时对加载的程序类重新定义,以使所述运行系统在利用重新定义的程序类创建目标对象时获得所述识别目标对象的对象标识。
29.根据权利要求28所述的跟踪系统,其中所述修改工具被进一步配置成:为所述程序类的字段添加附加的字段;对该类的构造函数进行修改,以使所述运行系统在创建目标对象时对所述附加字段赋值,得到代表所创建目标对象的标识。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CNA2008100061781A CN101515248A (zh) | 2008-02-21 | 2008-02-21 | 面向对象程序的跟踪方法和系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CNA2008100061781A CN101515248A (zh) | 2008-02-21 | 2008-02-21 | 面向对象程序的跟踪方法和系统 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN101515248A true CN101515248A (zh) | 2009-08-26 |
Family
ID=41039711
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CNA2008100061781A Pending CN101515248A (zh) | 2008-02-21 | 2008-02-21 | 面向对象程序的跟踪方法和系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN101515248A (zh) |
Cited By (19)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102169450A (zh) * | 2010-02-26 | 2011-08-31 | 国际商业机器公司 | 在ide中提示程序修改对程序性能的影响的方法和装置 |
CN102932464A (zh) * | 2012-11-06 | 2013-02-13 | 无锡江南计算技术研究所 | 一种存储系统的性能分析方法及装置 |
CN103365931A (zh) * | 2012-04-10 | 2013-10-23 | 中兴通讯股份有限公司 | 性能分析工具中快速定位函数性能记录的方法及装置 |
CN103605554A (zh) * | 2012-06-26 | 2014-02-26 | 马维尔国际贸易有限公司 | 用于代码性能分析的方法和装置 |
CN104142817A (zh) * | 2013-05-10 | 2014-11-12 | 中国电信股份有限公司 | 在Java应用中测量用户资源使用量的方法与装置 |
CN105683924A (zh) * | 2013-06-06 | 2016-06-15 | 微软技术许可有限责任公司 | 通过从在本机模式中执行转变为在经解释的模式中执行来调试本机代码 |
CN105808576A (zh) * | 2014-12-30 | 2016-07-27 | 展讯通信(天津)有限公司 | 一种数据记录系统及方法 |
CN107273264A (zh) * | 2017-06-08 | 2017-10-20 | 携程旅游网络技术(上海)有限公司 | 对象实例关键属性及其关联属性的跟踪方法及装置 |
WO2017193763A1 (zh) * | 2016-05-10 | 2017-11-16 | 中兴通讯股份有限公司 | 一种检测方法、装置及系统 |
CN107450946A (zh) * | 2017-07-24 | 2017-12-08 | 平安科技(深圳)有限公司 | Chrome网页与终端软件通讯方法、设备及存储介质 |
CN109684027A (zh) * | 2017-10-18 | 2019-04-26 | 北京京东尚科信息技术有限公司 | 动态跟踪Java虚拟机运行的方法和装置 |
CN110058859A (zh) * | 2018-01-18 | 2019-07-26 | 阿里巴巴集团控股有限公司 | 程序运行及虚拟机实例的实现方法、装置、设备及介质 |
CN110214313A (zh) * | 2016-11-27 | 2019-09-06 | 亚马逊技术股份有限公司 | 分布式代码跟踪系统 |
CN110389899A (zh) * | 2019-06-21 | 2019-10-29 | 北京字节跳动网络技术有限公司 | 检测js程序的api数据类型的方法装置、介质和设备 |
CN112041824A (zh) * | 2018-04-27 | 2020-12-04 | 微软技术许可有限责任公司 | 计算机过程执行的选择性跟踪部分 |
CN112041823A (zh) * | 2018-04-27 | 2020-12-04 | 微软技术许可有限责任公司 | 计算机过程执行的选择性跟踪部分 |
CN112256570A (zh) * | 2020-10-19 | 2021-01-22 | 网易(杭州)网络有限公司 | 远程调试方法、装置、设备及存储介质 |
CN112306723A (zh) * | 2019-07-30 | 2021-02-02 | 北京京东尚科信息技术有限公司 | 一种应用于小程序的运行信息获取方法和装置 |
CN117435440A (zh) * | 2023-12-20 | 2024-01-23 | 麒麟软件有限公司 | 一种程序堆空间的动态分析方法及系统 |
-
2008
- 2008-02-21 CN CNA2008100061781A patent/CN101515248A/zh active Pending
Cited By (32)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102169450A (zh) * | 2010-02-26 | 2011-08-31 | 国际商业机器公司 | 在ide中提示程序修改对程序性能的影响的方法和装置 |
CN103365931A (zh) * | 2012-04-10 | 2013-10-23 | 中兴通讯股份有限公司 | 性能分析工具中快速定位函数性能记录的方法及装置 |
CN103365931B (zh) * | 2012-04-10 | 2016-12-14 | 南京中兴新软件有限责任公司 | 性能分析工具中快速定位函数性能记录的方法及装置 |
CN103605554A (zh) * | 2012-06-26 | 2014-02-26 | 马维尔国际贸易有限公司 | 用于代码性能分析的方法和装置 |
CN103605554B (zh) * | 2012-06-26 | 2018-04-13 | 马维尔国际贸易有限公司 | 用于代码性能分析的方法和装置 |
CN102932464A (zh) * | 2012-11-06 | 2013-02-13 | 无锡江南计算技术研究所 | 一种存储系统的性能分析方法及装置 |
CN102932464B (zh) * | 2012-11-06 | 2015-10-07 | 无锡江南计算技术研究所 | 一种存储系统的性能分析方法及装置 |
CN104142817B (zh) * | 2013-05-10 | 2017-08-22 | 中国电信股份有限公司 | 在Java应用中测量用户资源使用量的方法与装置 |
CN104142817A (zh) * | 2013-05-10 | 2014-11-12 | 中国电信股份有限公司 | 在Java应用中测量用户资源使用量的方法与装置 |
CN105683924B (zh) * | 2013-06-06 | 2019-03-19 | 微软技术许可有限责任公司 | 用于调试本机代码的方法和系统 |
US10127138B2 (en) | 2013-06-06 | 2018-11-13 | Microsoft Technology Licensing, Llc. | Debugging native code by transitioning from execution in native mode to execution in interpreted mode |
CN105683924A (zh) * | 2013-06-06 | 2016-06-15 | 微软技术许可有限责任公司 | 通过从在本机模式中执行转变为在经解释的模式中执行来调试本机代码 |
CN105808576A (zh) * | 2014-12-30 | 2016-07-27 | 展讯通信(天津)有限公司 | 一种数据记录系统及方法 |
CN105808576B (zh) * | 2014-12-30 | 2019-05-28 | 展讯通信(天津)有限公司 | 一种数据记录系统及方法 |
WO2017193763A1 (zh) * | 2016-05-10 | 2017-11-16 | 中兴通讯股份有限公司 | 一种检测方法、装置及系统 |
CN110214313B (zh) * | 2016-11-27 | 2023-03-14 | 亚马逊技术股份有限公司 | 分布式代码跟踪系统 |
US11609839B2 (en) | 2016-11-27 | 2023-03-21 | Amazon Technologies, Inc. | Distributed code tracing system |
CN110214313A (zh) * | 2016-11-27 | 2019-09-06 | 亚马逊技术股份有限公司 | 分布式代码跟踪系统 |
CN107273264A (zh) * | 2017-06-08 | 2017-10-20 | 携程旅游网络技术(上海)有限公司 | 对象实例关键属性及其关联属性的跟踪方法及装置 |
CN107450946A (zh) * | 2017-07-24 | 2017-12-08 | 平安科技(深圳)有限公司 | Chrome网页与终端软件通讯方法、设备及存储介质 |
CN109684027A (zh) * | 2017-10-18 | 2019-04-26 | 北京京东尚科信息技术有限公司 | 动态跟踪Java虚拟机运行的方法和装置 |
CN110058859A (zh) * | 2018-01-18 | 2019-07-26 | 阿里巴巴集团控股有限公司 | 程序运行及虚拟机实例的实现方法、装置、设备及介质 |
CN110058859B (zh) * | 2018-01-18 | 2023-09-08 | 斑马智行网络(香港)有限公司 | 程序运行及虚拟机实例的实现方法、装置、设备及介质 |
CN112041824A (zh) * | 2018-04-27 | 2020-12-04 | 微软技术许可有限责任公司 | 计算机过程执行的选择性跟踪部分 |
CN112041823A (zh) * | 2018-04-27 | 2020-12-04 | 微软技术许可有限责任公司 | 计算机过程执行的选择性跟踪部分 |
CN110389899A (zh) * | 2019-06-21 | 2019-10-29 | 北京字节跳动网络技术有限公司 | 检测js程序的api数据类型的方法装置、介质和设备 |
CN110389899B (zh) * | 2019-06-21 | 2023-12-19 | 北京字节跳动网络技术有限公司 | 检测js程序的api数据类型的方法装置、介质和设备 |
CN112306723A (zh) * | 2019-07-30 | 2021-02-02 | 北京京东尚科信息技术有限公司 | 一种应用于小程序的运行信息获取方法和装置 |
CN112256570A (zh) * | 2020-10-19 | 2021-01-22 | 网易(杭州)网络有限公司 | 远程调试方法、装置、设备及存储介质 |
CN112256570B (zh) * | 2020-10-19 | 2023-08-11 | 网易(杭州)网络有限公司 | 远程调试方法、装置、设备及存储介质 |
CN117435440A (zh) * | 2023-12-20 | 2024-01-23 | 麒麟软件有限公司 | 一种程序堆空间的动态分析方法及系统 |
CN117435440B (zh) * | 2023-12-20 | 2024-04-05 | 麒麟软件有限公司 | 一种程序堆空间的动态分析方法及系统 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN101515248A (zh) | 面向对象程序的跟踪方法和系统 | |
US6557168B1 (en) | System and method for minimizing inter-application interference among static synchronized methods | |
US7912877B2 (en) | Leveraging garbage collection to dynamically infer heap invariants | |
US7949848B2 (en) | Data processing apparatus, method and computer program product for reducing memory usage of an object oriented program | |
US6851114B1 (en) | Method for improving the performance of safe language multitasking | |
CN110955431A (zh) | 编译环境的处理方法及装置 | |
CN106033370B (zh) | 64位Java虚拟机的实现方法及装置 | |
US8056061B2 (en) | Data processing device and method using predesignated register | |
US8478738B2 (en) | Object deallocation system and method | |
US8296742B2 (en) | Automatic native generation | |
Wagner et al. | “Slimming” a Java virtual machine by way of cold code removal and optimistic partial program loading | |
US11474832B2 (en) | Intelligently determining a virtual machine configuration during runtime based on garbage collection characteristics | |
US20120005460A1 (en) | Instruction execution apparatus, instruction execution method, and instruction execution program | |
Peiris et al. | Automatically detecting" excessive dynamic memory allocations" software performance anti-pattern | |
De Sutter et al. | Combining global code and data compaction | |
US20060101439A1 (en) | Memory management in a managed code execution environment | |
CN109923527B (zh) | 可变类型建立器 | |
US20070240132A1 (en) | System and method for compiler interprocedural optimization having support for object files in libraries | |
JP3280322B2 (ja) | コンパイル方法、フレーム検出方法及び装置、コード破棄方法、並びにコンピュータ | |
Lance et al. | Bytecode-based Java program analysis | |
US11106522B1 (en) | Process memory resurrection: running code in-process after death | |
US11789863B2 (en) | On-the-fly remembered set data structure adaptation | |
US11875193B2 (en) | Tracking frame states of call stack frames including colorless roots | |
US11513954B2 (en) | Consolidated and concurrent remapping and identification for colorless roots | |
US11573794B2 (en) | Implementing state-based frame barriers to process colorless roots during concurrent execution |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
AD01 | Patent right deemed abandoned |
Effective date of abandoning: 20090826 |
|
C20 | Patent right or utility model deemed to be abandoned or is abandoned |