JPDA学习

一、JPDA简介

JPDA is a multi-tiered debugging architecture that allows tools developers to easily create debugger applications which run portably across platforms, virtual machine (VM) implementations and JDK versions.---文档原介绍, 我理解JPDA就是对Java整个调试和监控体系的集成,我们实际上开发时涉及到的所有应用程序监控和调试的渠道都由JPDA体系当中提供的标准接口组成。然后整个调试和监控的过程都需要遵循JPDA体系制定的规范。

JPDA由三个部分组成,分别为两套接口(JVMTI、JDI接口)和一个协议(JDWP协议)组成。架构图如下图所示(摘自Oracle官网)。

 

JPDA的三个组成部分按照抽象级别由低到高分别为JVMTI、JDWP、JDI。

 

1、JVMTI(Java Virtual Machine Tool Interface)

 

JVMTI介绍

JVMTI(JVM Tool Interface) 是一套native编程接口,位于jpda 最底层,它提供了检查在JVM中的应用程序状态、控制应用程序执行的渠道。JVMTI可以提供性能分析、debug、内存管理、线程分析等功能。 比如现在集团用的Arthas、(chaosblade-jvm)Java相关的故障注入功能、SkyWalking,包括我们的JDK自带的一些工具jstack、jconsole、jvisualvm等等底层都是通过JVMTI来进行实现的。

 

JVMTI构成

JVMTI它是由一堆jvmEvent组成。这些代码在jvm源码中才能看见,那么我们就得通过下载openJDK来观看JVM源码,在openjdk里的jvmti.h或者jvmti.xml文件中进行查看。实际上这些jvmEvent都存在一个结构体变量当中,如下图所示。这些事件根据性质又分为JVMPI和JVMDI, 也就是监控和调试接口。在Java5中JVMTI将这两套接口进行了合并。

 

 

JVMTI原理

在文档介绍中也说了是一套native编程接口,那么我们要使用这些接口的话就得去实现这些接口。JVMTI是基于事件驱动的,JVM会对内部的很多操作做一个事件埋点,每执行到这些操作JVM就会主动调用一些事件的回调接口(比如线程启动、类加载、作者回收、异常事件等等),这些接口可以供开发者扩展自己的逻辑, 一般地,我们需要实现一个Agent使用JVMTI的功能,具体是在Agent里面对JVMTI声明的jvmtiEvent事件做回调事件的注册。然后把这个Agent编译成动态链接库然后供Java程序来加载并进行使用。加载的时机分为两种: 程序启动之前和程序启动之后。

对于这个Agent的实现是需要涉及到C和C++代码的,虽然作者精通C和C++的拼写,但是这并不合适出现在文章中,实际上在Java5以后我们安装java环境后已经给我们实现了一个Agent动态链接库,这个库在我们每个安装了java环境的电脑下的jre/lib目录下如下图所示(这个库的源码就在jvm源码中对应invocationAdapter.c,后续会进行分析)。

 

有了这个动态链接库以后,我们写的JavaAgent就能够完成对JVMTI事件的回调注册了,这个机制叫做Java Instrument。我们顺着Java Instrument机制的原理来完成对JVMTI知识的学习。

 

Java Instrument介绍

Java Instrument是Java SE5的新特性, 通过这个机制Java编程人员可以构建一个独立于应用程序的Agent,借助这个Agent我们可以监测、调试甚至修改目标应用程序的运行。这个Agent会以一种jar包的形式供目标程序来调用。通过Agent我们就可以实现一种虚拟机级别的AOP解决方案, 相较于传统的jdk动态代理、cglibAOP方案来说,Instrument机制是完全无侵入式的,并且支持在目标应用程序运行以后再进行动态aop的操作。相较而言这种AOP机制适用范围更广,并且更加实用。

 

Java Instrument使用和原理

Java Instrument支持premain和agentmain两种方式来实现Agent的注入。区别在于注入的时机在目标程序启动之前还是目标程序启动之后,然后他们其底层操作其实都是触发对JVMTI的ClassFileLoadHook这个事件的回调来实现的。

premain: 如果使用premain来实现agent注入,那么我们在启动前要给程序设置一些命令参数,让程序在加载前调用agent, 那么在启动程序后我们可以达成一些我们对程序想要做的aop操作。就我个人理解而言,这种方式的aop比较轻量,但是没啥应用场景。

agentmain:它是在应用程序启动后我们还想对应用程序做一些aop操作,这个的话cglib、jdk动态代理肯定都是做不到的,实际上我们会启动一个进程去和目标应用程序的jvm进行通信,然后把我们的实现的Agent代码attach到目标jvm当中。通过进程通信的方式来让目标jvm解析通信请求并且执行相关的方法。这种方式的aop需要另启一个进程。在介绍方面讲的实践场景也基本都是通过agentmain来做的。

 

premain实践:

 

1、附正常代码,执行TestTransClass的Main()函数控制台会不停地打印111。

// TransClass.java 
public class TransClass {
    public TransClass() {
    }

    public int getNumber() {
        return 111;
    }
}


public class TestTransClass {
    public static void main(String[] args) throws InterruptedException {
        TransClass transClass = new TransClass();
        while (true) {
            Thread.sleep(2000);
            System.out.println("print number = " + transClass.getNumber());
        }
    }
}

2、开启premain agent注入,先编译一个输入222的TransClass字节码文件,然后写一个Agent程序(我这里叫AgentMain), 利用这个Agent程序我们可以完成对字节码文件的增强转换, 这个增强转换的实现是由我们自己来做的, 具体是写一个Transformer类实现ClassFileTransformer接口,并重写transform()方法来完成。在这里我们把getNumber()方法转成了输出222。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JPDA(Matlab)是一种用于航迹关联的算法,具体分为基于卡尔曼滤波、粒子滤波和启发式搜索三种实现方式。如果你对JPDA算法感兴趣,可以访问海神之光的个人主页获取相应的Matlab代码。通过使用这些代码,你可以学习和实践JPDA算法,并进行相关的仿真开发。此外,海神之光也提供其他多个Matlab仿真内容,例如图像处理、路径规划、神经网络预测与分类、优化求解、语音处理、信号处理和车间调度等领域。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【航迹关联】基于matlab NNDA+PDA+JPDA算法航迹关联【含Matlab源码 1928期】](https://blog.csdn.net/TIQCmatlab/article/details/125648565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [实现航迹关联的三种JPDA算法及Matlab代码](https://blog.csdn.net/code_welike/article/details/131862643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值