使用 Java Debug Interface(JDI)调试多线程应用程序
本文对 Java Debug Interface(JDI)及其使用进行了介绍,并通过实现一个多线程分析器的示例应用,演示了如何利用 JDI 开发自己的多线程调试程序。该示例分析器在独立于目标程序的前提下,以单个线程流为单位,帮助追踪记录多线程的执行过程信息。
多线程环境下的程序调试是让开发者头痛的问题。在 IDE 中通过添加断点的方式调试程序,往往会因为停在某一条线程的某个断点上而错失了其他线程的执行,线程之间的调度往往无法预期,并且会因为断点影响了实际的线程执行顺序。因此,在调试多线程程序时,开发者往往会选择打印 Trace Log 的方式来帮助调试。
使用 Log 来帮助调试的问题在于,开发者往往无法预期哪些关键点需要记录,于是在整个程序的调试过程中,需要不断的加入 Log 调用,编译生成可执行程序并部署,这对于大尺寸的软件开发项目无疑是噩梦,会直接影响到开发效率。
有没有一种办法,可以独立于程序代码,能在运行期间绑定到程序上并获取程序运行过程当中的关键信息呢?更重要的,这种方法应该是可定制的,开发者可以通过少量的努力,就可以达到特定的调试目的。答案是肯定的。通过使用 Java Debug Interface(JDI),开发者可以快速开发定制出适用于自己的线程 Profiling 工具。这样的工具独立于主程序,并且可高度定制。在接下来的文章中,我们将介绍如何实现该工具。
认识 JPDA 和 JDI
从 J2SE 1.3 开始,Java 开始提供了一套叫做 Java Platform Debugger Architecture(JPDA) 的架构,开发者可以通过这套架构来开发调试用程序。这套架构被主流的 Java IDE(如 Eclipse、NetBeans 等)广泛地采用。
JPDA 详情
更多关于 JPDA 的详细介绍,可以参见 JPDA 官方文档 以及 “深入 Java 调试体系”系列文章。
具体来说,JPDA 不仅仅是一套 API 的组合,也不只是一个具体的工具。这套架构提供了从目标程序、调试双方的信息协议,到供开发者使用的结构调用,都一一做出了定义。在 J2SE 5.0 中,它由三个部分组成:
Java Virtual Machine Tools Interface(JVMTI),是一套低级别的 native 接口。它定义了 Java 虚拟机所必需为调试提供的服务接口。JVMTI 在 Java 5.0 之前的前身是 JVMDI(Jave Virtual Machine Debug Interface)。
Java Debug Wire Protocol(JDWP),定义了调试双方信息和请求的文本格式。
Java Debuger Interface(JDI),定义了代码级别的调试接口。
从开发者的角度来看,调试工具的开发既可以基
相关文档:
Java, .Net发展方向和前景
JAVA语言发明已有10年历史,在IBM、SUN等公司的推动下已经比较稳定与成熟,获得了大规模企业的普遍应用。时至今日,J2EE已经发展成为一个覆盖面广,效率高,易用性强的技术平台,吸引了400万开发者,在网络技术遍及全球的的今天,更有17.5亿台设备使用JAVA技术.同时, Mustang版本的J2EE正在紧锣 ......
import java.awt.*;
import java.awt.event.*;
public class TestFrame {
Frame fm = new Frame();
public void init(){
fm.setSize(300,300);
Button btn = new Button("ok");
fm.add(btn);
btn.addActionListener(ne ......
请不要把你的学习Java之路和其它计算机技术分开看待,技术的联系往往是千丝万缕的,你应该掌握一些学习Java所涉及的基础知识,对于 “CLASSPATH要怎么设置啊”、“跪求JDK下载地址”等等问题,你不该问,因为Internet上太多答案了,甚至换个角度说,你是不是还不适合直接学习编程?
1)买本Java学习用 ......
先看看下面的代码,大家猜猜输出是什么
package com.captain.test;
public class ArrayTest {
public static void main(String[] args){
//新建一个对象(OneNum)数组(赋值为5、3、4)
OneNum[] ac = {new OneNum(5),new OneNum(3),new OneNum(4)};
//新建一个与ac同长度的对象(OneNum)数组
OneNum[] n ......
1,一行代码做一件事,不要在一行代码里面处理多件事。宁愿多声明几个变量,也要保持代码的清晰,因为代码的声明并不会占多少内存。
例如:
String tmpa = errIdList.get(i).toString().substring(2);
......