`
ayufox
  • 浏览: 276675 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[Java性能剖析]JPDA 3)JDI/Debuger

    博客分类:
  • JVM
阅读更多

     参考:http://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html
     JDI(Java Debug Interface)为Java调试器的开发提供了标准的接口,我们可以通过此构建标准的Java调试器。如JPDA架构图所示,通过Front-end、Transport(交互机制)和Back-end的交互,JDI对外使用Java语言提供了一个JVM TI的功能子集的高级接口(并非所有JVM TI功能都可以通过JDI访问到)。需要注意的是,JDI实现上不会太多考虑性能上的问题,因此一般不会使用JDI来构建性能剖析相关工具。
     1.主要的API

  • com.sun.jdi.connect.AttachingConnector:连接器,通过该连接器可以连接到一个运行中的JVM上
  • com.sun.jdi.VirtualMachine:远程/本地运行JVM的映像,类似于JVM TI中的jvmEnv对象
  • com.sun.jdi.request.EventRequestManager:事件请求管理器,通过该管理器进行事件注册
  • com.sun.jdi.ThreadReference:线程引用,可以通过此类获得线程相关的信息,譬如线程状态、线程栈等

     2.范例
     我们通过一个范例来了解一下JDI的使用,本范例首先获取到当前所有线程的信息,然后注册方法进入和退出事件,同时打印进入和退出信息。(如下程序需要tools.jar包)
     1)在被调试的JVM上启动调试Back end:在被调试的JVM启动参数中增加如下参数

-agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n

    具体参数的配置可参见《Connection and Invocation Details
     2)连接到被调试的JVM上
     由于Back-end的transport使用的是dt_socket的方式,首先需要获得一个dt_socket的AttachConnector

VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();
List connectors = vmManager.attachingConnectors();
AttachingConnector socketAttachingConnector = null;
for (int i = 0; i < connectors.size(); i++)
{
        Connector connector = (Connector) connectors.get(i);
        Transport transport = connector.transport();
        if (”dt_socket”.equals(transport.name()))
        {
            socketAttachingConnector = (AttachingConnector) connector;
            break;
        }
}

     连接到被调试的JVM上

Map arguments = socketAttachingConnector.defaultArguments();
Connector.Argument hostArg = (Connector.Argument) arguments.get(HOST);
Connector.Argument portArg = (Connector.Argument) arguments.get(PORT);

hostArg.setValue(“127.0.0.1”);
portArg.setValue(“8000”);

VirtualMachine jvm = socketAttachingConnector.attach(arguments);

     3)打印当前线程信息

List<ThreadReference> threadReferences = jvm.allThreads();
for (ThreadReference tr : threadReferences)
{
      System.out.print("Thread[" + tr.name() + "] : ");
      //线程状态
      switch (tr.status())
       {
            case ThreadReference.THREAD_STATUS_MONITOR:
                System.out.println(" Waiting");
                break;
            case ThreadReference.THREAD_STATUS_NOT_STARTED:
                System.out.println(" Not Start");
                break;
            case ThreadReference.THREAD_STATUS_RUNNING:
                System.out.println(" Running");
                break;
            case ThreadReference.THREAD_STATUS_SLEEPING:
                System.out.println(" Sleepping");
                break;
            case ThreadReference.THREAD_STATUS_UNKNOWN:
                System.out.println(" Unknow");
                break;
            case ThreadReference.THREAD_STATUS_WAIT:
                System.out.println(" Wait");
                break;
            case ThreadReference.THREAD_STATUS_ZOMBIE:
                System.out.println(" Finish");
                break;
      }
       boolean suspend = tr.isSuspended();
       //注意,只有suspend的线程才能获得其线程栈,因此需要将其线suspend一下
       if (!suspend)
       {
           tr.suspend();
       }
        List<StackFrame> frames = tr.frames();
        for (StackFrame frame : frames)
       {
            System.out.println("-----"
                        + frame.location().method().toString() + ":"
                        + frame.location().lineNumber());
        }
           
         System.out.println("count:" + tr.entryCount());

         if (!suspend)
        {
              tr.resume();
        }
         frames = null;
}

     4)注册方法进入和退出事件,在实现调试器的时候,我们可以通过注册一个BreakPoint事件,在事件发生时挂住执行线程,然后检查事件发生对象的信息来实现最常见的断点调试功能,或者Step事件来完成单步执行功能

EventRequestManager eventRequestManager = jvm.eventRequestManager();
MethodEntryRequest methodEntryRequest = eventRequestManager.createMethodEntryRequest();
methodEntryRequest.addClassExclusionFilter("java.*");//设置过滤器,对过滤器中的Class不捕获其实践
methodEntryRequest.addClassExclusionFilter("sun.*");
methodEntryRequest.addClassExclusionFilter("javax.*");
methodEntryRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);//这个属性一定要设,
默认事件发生时会suspend住执行线程
methodEntryRequest.enable();
       
MethodExitRequest methodExitRequest = eventRequestManager.createMethodExitRequest();
methodExitRequest.addClassExclusionFilter("java.*");
methodExitRequest.addClassExclusionFilter("sun.*");
methodExitRequest.addClassExclusionFilter("javax.*");
methodExitRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
methodExitRequest.enable();

     5)处理事件

EventQueue eventQueue = jvm.eventQueue();
EventSet eventSet;
while (true)
{
    eventSet = eventQueue.remove();
    EventIterator eventIterator = eventSet.eventIterator();
    while (eventIterator.hasNext())
    {
            Event event = (Event) eventIterator.next();
            execute(event);
    }
}

        打印处理信息

private void execute(Event event) throws Exception
{
	if (event instanceof MethodEntryEvent)
	{
		System.out.println("Mehtod Entry:" + ((MethodEntryEvent) event).method());
	}
	else if (event instanceof MethodExitEvent)
	{
		System.out.println("Mehtod Exi:" + ((MethodExitEvent) event).method());
	} 
}
 
5
0
分享到:
评论
1 楼 jk19910410 2012-01-31  
vmManager.attachingConnectors();  报NullpointExcepiton怎么回事?

相关推荐

    JPDA----java调试体系

    JPDA 主要由三个部分组成:Java 虚拟机工具接口(JVMTI),Java 调试线协议(JDWP),以及 Java 调试接口(JDI)。 JPDA 概述 ---------------- JPDA 是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发...

    深入Java调试体系(JPDA-JDWP)

    JPDA 主要由三个部分组成:Java 虚拟机工具接口(JVMTI),Java 调试线协议(JDWP),以及 Java 调试接口(JDI),本系列将会详细介绍这三个模块的内部细节、通过实例为读者揭开 JPDA 的面纱。

    基于JPDA的Java软件性能测试.pdf

    在基于JPDA的Java软件性能测试中,JPDA平台可以帮助开发者快速地对Java程序的性能和稳定性进行检测和分析,从而提高软件的整体质量。 基于JPDA的Java软件性能测试可以通过JPDA平台来进行简化测试,提高认软件的性能...

    JPDA学习笔记与示例代码

    JPDA由三部分组成:Java Debug Wire Protocol (JDWP),Java Debug Interface (JDI) 和Java Debugger Interface (JDI参考实现)。JDWP是调试器和虚拟机之间的通信协议,JDI是Java编程接口,提供了调试功能,而JDI参考...

    JPDA.rar_JPDA数据关联_jpda_jpda关联_数据关联JPDA_跟踪波门

    标题中的"JPDA.rar"可能是指Java Platform Debugger Architecture(Java平台调试架构)的压缩文件,而"JPDA数据关联_jpda_jpda关联_数据关联JPDA_跟踪波门"这部分描述了与JPDA相关的特定应用或概念,特别是关于数据...

    使用JPDA进行Java程序远程调试

    Java Platform Debugger Architecture (JPDA) 是Java开发工具的一部分,它为开发者提供了强大的远程调试功能,使得可以在一台机器上调试运行在另一台机器上的Java应用程序。本文将详细介绍如何使用JPDA进行Java程序...

    7_目标跟踪_jpda.zip

    JPDA由三部分组成:Java虚拟机工具接口(JVM TI),Java调试接口(JDI),以及Java调试协议(JDWP)。这些组件协同工作,使得开发者可以对程序进行断点设置、变量查看、线程管理等调试操作。 目标跟踪在软件开发中...

    JPDA_jpda_目标跟踪_源码

    2. **Java Debug Interface (JDI)**:这是一个Java API,供调试器使用,以控制被调试的Java应用程序或虚拟机。 3. **Java Virtual Machine Tool Interface (JVMTI)**:这是Java虚拟机提供的一组回调函数,允许工具...

    Java调试体系及协议

    3. **Java Debug Wire Protocol (JDWP)**: JDWP是JDI和JVMTI之间的通信协议,负责在调试器和被调试的Java虚拟机之间传输调试信息。它是基于TCP/IP的,允许远程调试。JDWP定义了一套命令集,用于数据交换,如对象引用...

    远程调试jpda.docx

    JPDA是Java平台调试架构,它由Java虚拟机后端和调试平台前端两部分构成,使得调试平台可以通过调试交互协议向Java虚拟机请求服务,从而对运行在虚拟机中的程序进行调试。 具体到本文中,我们的应用服务器是Tomcat ...

    JPDA文章汇总

    JPDA常用于远程调试、自动化测试、性能分析等场合,特别适合分布式系统或云环境中的Java应用调试。 6. **源码分析:** 在“DemoCode”中,可能包含了利用JPDA进行调试的示例代码。通过分析这些代码,我们可以了解...

    JPDA_suanfa_jpda_航迹关联_JPDAmatlab仿真_

    3. **调整参数:** 修改参数,比如传感器性能、目标运动模型等,观察这些变化对结果的影响。 4. **比较分析:** 可以对比其他数据关联算法(如Kalman滤波、概率数据关联PDA等),加深对JPDA的理解。 总之,这个...

    Matlab_JPDA.zip_JPDA matlab仿真_JPDA算法_jpda_jpda tracking_matlab j

    多目标跟踪JPDA算法实现,是学习JPDA算法的经典代码,建议下载下来看看。

    7_目标跟踪_jpda_源码.zip

    标题中的“7_目标跟踪_jpda_源码.zip”表明这是一个关于目标跟踪技术的资料,其中包含了JPDA(Java Platform Debugger Architecture)的源代码。这个主题涉及到的是软件开发中的调试技术,特别是针对Java平台的调试...

    Java程序优化与数据竞争检测的研究.pdf

    本文对Java程序优化与数据竞争检测的研究结果表明,Java程序优化是提高Java程序性能的重要手段,而JPDA平台是检测Java程序性能的重要技术。因此,在实际应用中,应充分利用Java程序优化和JPDA平台技术,提高Java程序...

    JPDA算法程序.zip

    通过运行这些程序,用户可以模拟不同的雷达跟踪场景,调整参数以适应特定的杂波环境,或者评估不同初始条件下的跟踪性能。 **文件列表分析** 由于提供的文件列表只有一个:"JPDA算法程序",可以推断这可能是一个...

Global site tag (gtag.js) - Google Analytics