使用 Java 虚拟机工具接口(JVMTI)创建调试和分析代理

豆豆网   技术应用频道   2009年03月12日  【字号: 收藏本文

本文阐述如何使用 JVMTI 创建 Java 应用程序的调试和分析工具。这种工具(也称作代理)在应用程序中发生事件时,能够使用该接口提供的功能对事件通知进行注册,并查询和控制该应用程序。

  使用 JVMTI 分析线程

  本节介绍如何获取关于在 JVM 中运行的用户线程的信息。如前所述,启动 JVM 时,JVMTI 代理库中的启动函数 Agent_OnLoad将被调用。在 VM 初始化过程中,JVMTI_EVENT_VM_INIT类型的 JVMTI Event 将生成并被发送到代理代码的 callbackVMInit例程中。一旦 VM 初始化事件被接收(即 调用VMInit回调),代理即可结束其初始化。现在,此代理可以自由调用任何 Java Native Interface (JNI) 或 JVMTI 函数。此时,我们已经处于活动阶段,将启用本 VMInit 回调例程中的 Exception事件(JVMTI_EVENT_EXCEPTION)。

error = (*jvmti)->SetEventNotificationMode
      (jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, (jthread)NULL);

  无论何时,只要在 Java 编程语言方法中首次探测到异常,就会生成 Exception事件。此异常可能由 Java 编程语言抛出,也可能由本地方法抛出;但是如果由本地方法抛出,直到 Java 编程语言方法首次发现此异常时该事件才会生成。如果异常已被处理并清除,则异常事件不会生成。

  出于演示目的,下面给出了所用的示例 Java 应用程序。主线程创建了 5 个线程,这 5 个线程退出前各自抛出一个异常。一旦启动 JVM,JVMTI_EVENT_VM_INIT将生成并被发送到代理代码中进行处理,因为我们已经在代理代码中启用了 VMInit和 Exception事件。随后,当 Java 线程抛出一个异常时,JVMTI_EVENT_EXCEPTION将被发送到代理代码中。然后,代理代码 会分析此线程信息并显示当前线程名、它所属的线程组、此线程所拥有的监视器、线程状态、线程堆栈跟踪及 JVM 中的所有用户线程。

 public class SimpleThread {
      static MyThread t;
      public static void main(String args[]) throws Throwable{
      t = new MyThread();
      System.out.println("Creating and running 10 threads...");
      for(int i = 0; i < 5; i++) {
      Thread thr = new Thread(t,"MyThread"+i);
      thr.start();
      try {
      thr.join();
      } catch (Throwable t) {
      }
      }
      }
      }
      class MyThread implements Runnable {
      Thread t;
      public MyThread() {
      }
      public void run() {
      /* NO-OP */
      try {
      "a".getBytes("ASCII");
      throwException();
      Thread.sleep(1000);
      } catch (java.lang.InterruptedException e){
      e.printStackTrace();
      } catch (Throwable t) {
      }
      }
      public void throwException() throws Throwable{
      throw new Exception("Thread Exception from MyThread");
      }
      } 

来源:BlogJava    作者:舵手    责编:豆豆技术应用

正在加载评论...