Java 调试技术 JPDA 架构解读,java二次开发面试题

  1. 如果 JDI/JDWP 所包含的功能不满足我们的需求,例如堆栈分析,那么我们可以直接通过 JVMTI 来实现我们想要的功能。

JVMTI 规范所对应的功能是最完整的,而 JDWP 仅支持部分功能,JDI 则仅支持调试相关的功能。在功能上,是父子集的关系。

通信机制

调试器与被调试JVM之间需要通过一定的方式进行通信,通信的机制主要包括两部分

  1. 连接器(Connector)

  2. 通信方式(Transport)

连接器是指调试器与被调试 JVM 之间的一个连接,JPDA 在 JDI 这一层面实现了连接器。

通信方式是指调试器与被调试 JVM 之间的数据交换方式和通信报文格式,JPDA 在 JDWP 中定义了报文规范。

连接器

连接器有三种:

  1. Listening:调试器监听来自被调试 JVM 的连接;

  2. Attaching:调试器连接上一个已经处于运行状态的被调试 JVM;

  3. Launching:调试器直接亲手启动被调试 JVM,此时调试器与被调试代码实际上是运行在同一个 JVM 中的;

通信方式

调试器与被调试 JVM 之间的数据交换方式,有两种:

  1. 基于 Socket 网络连接,主要用于远程调试,即调试器和被调试 JVM 不在同一台机器上;

基于 Socket 的网络连接

  1. 基于操作系统共享内存的通信,主要用于调试器和被调试 JVM 在同一台机器上的情况;

基于共享内存的连接

配置

调试器和被调试 JVM 在启动的时候, 都需要通过设置 JVM 参数来让它具有调试的能力或者可被调试的能力。

对于 JDK5 及以上的版本,参数格式为:-agentlib:jdwp={子配置项}

对于 JDK5 以前的版本,参数格式为:-Xdebug 以及 -Xrunjdwp:{子配置项}

而子配置项,包括:

  1. transport:数据交换方式,可选:dt_socketdt_shmem,分别代表 socket 网络通信和共享内存通信

  2. Address:标识一个对端的地址,格式为:{ip}:{port}

  3. server:标识自己是调试者还是被调试者,调试者配置为:n,被调试着配置为:y

  4. suspend:只有被调试者才需要配这个参数,当配置为 y 的时候,代表等待调试者连接上来才真正启动 Java 应用;配置为 n 时,则直接启动 Java 应用。

这里的 Java 应用,是相对于 JVM 来说的,假如把 JVM 看成一个平台,那我们写的代码就是一个 Java 应用。JVM 已经启动,但我们的应用代码还没有跑起来,这种情况在上文的语境中,我 需要zi料+ 绿色徽【vip1024b】

们叫做 Java 应用还没启动。

配置示例:

  1. 被调试者开启远程调试监听:

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

复制代码

  1. 被调试者开启本地共享内存调试监听:

-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n

复制代码

  1. 调试者远程连接被调试者:

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

复制代码

  1. 调试者基于共享内存方式连接被调试者:

-agentlib:jdwp=transport=dt_shmem, address=

复制代码

  1. 调试者基于共享内存方式启动被调试者:

-agentlib:jdwp=transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe

复制代码

被调试者基于共享内存的监听启动后,共享内存地址将会打印到控制台上。调试者配置时需要配置这个共享内存的地址

JDI


功能

  1. 提供了跟调试相关的 Java API;

  2. 能够获取一个正在运行的 JVM 的状态,包括:类,数组,接口,基本类型以及这些类型的对象数量;

  3. 与执行相关的控制,例如暂停和恢复线程;

  4. 设置断点,监听异常的发生、类加载、线程创建等;

  5. 提供不同的连接器实现,例如基于 socket 的远程连接器和基于共享内存的本地连接器;

技术架构

JDI技术架构

  1. 提供事件机制

  2. 对 JDWP 协议的编解码

用法

要使用 JDI 的功能,需要依赖 JDK 自带的 tools.jar 这个工具包,JDI 相关的代码处于 com.sun.jdi 这个包下面。

一个大致的使用步骤如下所示:

  1. 获取一个 VirtualMachine 实例

  2. VirtualMachine 实例中获取一个 Connector

  3. 使用 VirtualMachineEventRequestManager 来监听我们感兴趣的事件

事件机制代码示例:

EventRequestManager em=vm.eventRequestManager();

MethodEntryRequest meR=em.createMethodEntryRequest();

meR.addClassFilter(“mypckg.*”);

meR.enable();

EventQueue eventQ=vm.eventQueue();

while (running) {

EventSet eventSet=null;

总结

本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!

MySQL50道高频面试题整理:

m.eventQueue();

while (running) {

EventSet eventSet=null;

总结

本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!

MySQL50道高频面试题整理:

[外链图片转存中…(img-cNatMEms-1710351066937)]

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值