设为首页收藏本站language 语言切换
查看: 1433|回复: 0
收起左侧

Java进阶:使用 JDI 调试多线程应用程序

[复制链接]
发表于 2010-2-20 15:08:33 | 显示全部楼层 |阅读模式
<p >本文对 Java Debug Interface(JDI)及其使用进行了介绍,并通过实现一个多线程分析器的示例应用,演示了如何利用 JDI 开发自己的多线程调试程序。该示例分析器在独立于目标程序的前提下,以单个线程流为单位,帮助追踪记录多线程的执行过程信息。<p ><p >多线程环境下的程序调试是让开发者头痛的问题。在 IDE 中通过添加断点的方式调试程序,往往会因为停在某一条线程的某个断点上而错失了其他线程的执行,线程之间的调度往往无法预期,并且会因为断点影响了实际的线程执行顺序。因此,在调试多线程程序时,开发者往往会选择打印 Trace Log 的方式来帮助调试。<p ><p >使用 Log 来帮助调试的问题在于,开发者往往无法预期哪些关键点需要记录,于是在整个程序的调试过程中,需要不断的加入 Log 调用,编译生成可执行程序并部署,这对于大尺寸的软件开发项目无疑是噩梦,会直接影响到开发效率。<p ><p >有没有一种办法,可以独立于程序代码,能在运行期间绑定到程序上并获取程序运行过程当中的关键信息呢?更重要的,这种方法应该是可定制的,开发者可以通过少量的努力,就可以达到特定的调试目的。答案是肯定的。通过使用 Java Debug Interface(JDI),开发者可以快速开发定制出适用于自己的线程 Profiling 工具。这样的工具独立于主程序,并且可高度定制。在接下来的文章中,我们将介绍如何实现该工具。<p ><p ><b>认识 JPDA 和 JDI</b><p ><p >从 J2SE 1.3 开始,Java 开始提供了一套叫做 Java Platform Debugger Architecture(JPDA) 的架构,开发者可以通过这套架构来开发调试用程序。这套架构被主流的 Java IDE(如 Eclipse、NetBeans 等)广泛地采用。<p >具体来说,JPDA 不仅仅是一套 API 的组合,也不只是一个具体的工具。这套架构提供了从目标程序、调试双方的信息协议,到供开发者使用的结构调用,都一一做出了定义。在 J2SE 5.0 中,它由三个部分组成:<p ><p >1.Java Virtual Machine Tools Interface(JVMTI),是一套低级别的 native 接口。它定义了 Java 虚拟机所必需为调试提供的服务接口。JVMTI 在 Java 5.0 之前的前身是 JVMDI(Jave Virtual Machine Debug Interface)。<p ><p >2.Java Debug Wire Protocol(JDWP),定义了调试双方信息和请求的文本格式。<p ><p >3.Java Debuger Interface(JDI),定义了代码级别的调试接口。<p ><p >从开发者的角度来看,调试工具的开发既可以基于 JVMTI 也可以基于 JDI。JVMTI 是 native 接口,使用起来相对复杂,并且需要 C 语言的基础,因此,在本文中,我们将介绍如何使用 JDI 这种最上层的方式来开发 Java 调试程序。<p ><p ><b>需求分析</b><p ><p >在接下的部分,我们将介绍如何使用 JDI 来开发一个用来调试多线程程序的工具。在开始前,让我们先列出这个工具需要满足的功能:<p ><p >1.独立于目标应用程序的。<p >2.应该足够简单,并且能在通过少量的代码修改就能完成集中配置,这样是帮助开发者不需要付出太多的努力就能开始调试自己的多线程程序。<p >3.能够抓取足够的信息,比如说异常的信息,程序调用过程中的变量值等等。<p >4.所生成的 Log 应该足够清晰,能够按不同的线程来分离记录,而不是按照时间的顺序来生成每一条记录,否则会给调试带来不便。<p ><p ><b>实现</b><p ><p >在文章最后的 示例代码 中,我们展示了一个典型的基于 JDI 的调试工具逻辑,并且用它来 Profile 一个简单的多线程程序的执行。根据前面所提到的需求,代码展示了线程运行栈快照、方法调用的入口参数值收集、异常过滤定制、类过滤配置、线程 Log 记录等功能。具体来说:<p ><p >1.独立于目标程序 <p >分析工具可以通过如下方式启动:<p ><p >java Trace options class args <p ><p >支持的 options 参数:<p ><p >-output 文件名:工具生成的 Log 的路径<p ><p >class 是目标程序的入口类,args 为目标程序的输入参数<p ><p >2.简洁配置 <p >a.异常过滤配置: <p >您可以在 ExceptionConfig.properties 属性文件中配置所需记录异常类型。在 Demo 代码中配置了对于 NullPointerException 和 UserDefinedException 两种异常,分析工具将追踪这两种异常情况。<p ><p >ExceptionName = exceptions.UserDefinedException;java.lang.NullPointerException<p ><p >b.类过滤配置: <p >您可以在 ClassExcludeConfig.properties 属性文件中配置被过滤的类模式,分析工具将不会处理被过滤类的任何事件。<p ><p >ExcludedClassPattern=java.*;javax.*;sun.*;com.sun.*;com.ibm.*<p ><p >3.运行 <p >在目标的主程序的生命周期中,分析器完成以下操作:<p ><p >1.绑定,分析工具和目标调试程序的虚拟机实例绑定;<p >2.事件注册,分析工具向虚拟机实例注册相关事件请求,整个分析过程采取基于事件驱动的模式。<p >3.线程运行时信息挖掘。<p >4.分类信息生成。<p >以上四点操作满足了需求:通过采用绑定机制实现调试程序和工具程序的独立,分析工具和目标程序以监听端口、共享内存等方式进行通信,无须目标程序进行任何代码修改即可实现调试。采用基于事件的机制可以帮助开发者依据实际需要集中注册和处理事件。作为基础框架,分析工具注册了支持异常、执行流程等事件,并提供了异常时运行栈快照,方法进出参数记录等功能实现信息抓取。支持单线程为单位的 Log 记录,将开发者从无序不可预测的多线程执行中摆脱出来,对调试程序提供帮助。<p ><p >下面将详细阐述实现步骤:<p ><p >绑定<p ><p >JDI 支持四种对目标程序的绑定方式,分别为:<p ><p >1.分析器启动目标程序虚拟机实例<p >2.分析器绑定到已运行的目标程序虚拟机实例<p >3.目标程序虚拟机实例绑定到已运行的分析器<p >4.目标程序虚拟机实例启动分析器<p >JDI 支持一个分析器绑定多个目标程序,但一个目标程序只能绑定一个分析器。为支持以上绑定,JDI 对应有 LaunchingConnector,AttachingConnector 和 ListeningConnector,具体类介绍可以参照 文档。<p ><p >本文采用第一种绑定方式阐述如何开发定制的多线程分析器,其它绑定方式可以参照 文档。<p ><p >绑定过程分为三个步骤:<p ><p >1.获取连接实例 <p ><p >清单 1. 获取连接实例<p ><ccid_nobr><table width="400" border="1" cellspacing="0" cellpadding="2"  bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code" ><pre><ccid_code>LaunchingConnector findLaunchingConnector() {    List connectors = Bootstrap.virtualMachineManager().allConnectors();    Iterator iter = connectors.iterator();    while (iter.hasNext()) {            Connector connector = (Connector) iter.next();            if (&quot;com.sun.jdi.CommandLineLaunch&quot;.equals(connector.name())) {            return (LaunchingConnector) connector;        }  }}</ccid_code></pre></td></tr></table></ccid_nobr><br><p ><p >Bootstrap.virtualMachineManager().allConnectors() 返回所有已知的 Connector 对象实例。选择返回 com.sun.jdi.CommandLineLaunch 连接实例,表示使用第一种绑定方式。                                 <p align="center"><font color="FF0000" >1</font>234<span class="content01">下一页&gt;&gt;</span></p></p>
您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-4-6 07:15 , Processed in 0.163170 second(s), 24 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表