首页 » 网站推广 » phpzookeeperdll技巧_底层技能揭秘java调试对象实现事理与运用技巧

phpzookeeperdll技巧_底层技能揭秘java调试对象实现事理与运用技巧

访客 2024-11-01 0

扫一扫用手机浏览

文章目录 [+]

文 吴潇/Java高等工程师

java 技能栈的程序员大多利用过远程调试。
如果你还没有用过java远程调试,请仔细看一看本篇文章第一小节,查问题效率立即提升数倍;对付利用过java远程调试的老手来说,有没有想过它的底层是怎么实现的呢?本日这篇文章就来揭秘(程序员该当理解自己每天利用的工具,磨炼自己的技艺)

phpzookeeperdll技巧_底层技能揭秘java调试对象实现事理与运用技巧

1. Java远程调试基本操作

Java进程默认不支持远程调试,如果须要远程调试,必须在启动java之前加上特定选项。

phpzookeeperdll技巧_底层技能揭秘java调试对象实现事理与运用技巧
(图片来自网络侵删)

第一步、在启动JVM的时候,加上以下调试选项:

Java 5以前:-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044Java 5及往后:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044

两者之间有啥差异:

“-Xdebug -Xrunjdwp” 紧张用于Java 5以前。
个中,“-Xdebug”是让JVM开启调试支持,开启调试功能就会哀求jvm运行于阐明实行模式,因此,java程序的实行速率就变得非常非常慢;“-Xrunjdwp”是让JVM运行一个JDWP协议,从而许可远程调试。

-agentlib:jdwp 用于Java 5及往后,开启后JVM运行于JIT模式,速率更快。
由于Java 5采取了HotSpot VM,增加了动态反优化技能,使得调试速率更快。
通过这个选项长期开启调试支持也不会影响程序运行速率。
同时还支持热交流技能,使得在调试的过程中可以修正Class的代码,从而更快速地定位到问题。

以上两种办法,都须要进一步配置远程调试参数,即“runjdwp:”和“jdwp=”后面的选项。
选项详细配置如下。

第二步、在IntelliJ IDEA中,新建一个远程调试的运行配置(Run configuration):

第三步、点击调试按钮,就可以进行远程调试了。

把稳要知足以下条件:

要确保本地代码与远程代码同等;被调试的程序在编译的时候,加上了调试信息的(命令:javac -g ...)2. IntelliJ IDEA 或 Eclipse 如何实现调试功能的

有了远程调试履历的老手们可能会碰着一些实际问题。
例如,有的bug在线上能够稳定复现,但是当我们对目标程序进行调试的时候,这个bug竟然神奇般地消逝了。
你有碰着过这样的问题吗?我就碰着过这样的问题。
正是我碰着的这个诡异征象匆匆使我全面理解了一遍java远程调试到底是怎么实现的,它对目标程序自身有什么影响?

比如,我们在debug一段程序的时候,须要设置断点,然后再单步实行。
当程序运行到某个断点位置时,这个线程就会被suspend,等待我们的debugger见告目标程序,下一步要怎么实行,是step还是resume还是run to cursor等。
如果我们正在单步实行,又有新线程命中这个断点,那么这个线程是会连续实行还是会suspend呢?我们在debug的过程中,线程被停息,GC又是怎么发生的,也被停息了吗?线程被我们的断点停息后,跟韶光干系的代码会把我们调试导致的停息的韶光也包含在内吗?诸如此类的问题,要想弄明白,都须要我们深入理解java远程调试这个底层技能。

3. Java Platform Debugger Architecture (JPDA)

JPDA是Java实现调试功能的架构设计,紧张目的是供应给工具开拓商开拓调试工具 (debugger application)。
JPDA担保了调试工具可跨平台、跨JVM、跨JDK版本运行。

JPDA是分层设计的,统共分3层:

Java VM Tool Interface (JVM TI): Java虚拟机工具接口层,位于JPDA最底层,卖力定义由JVM供应的调试做事的接口,而JVM卖力实现JVM TI接口。
可见,Java程序的调试也是按照SPI(Service Provier Interface)设计模式设计的,把JVM的调试能力看作一种做事,通过接口来对外供应这种做事,而JVM卖力调试功能的详细实现。
Java Debug Wire Protocol (JDWP):卖力被调试的进程和debugger前端之间的通信。
JVM TI供应的调试做事是面向native措辞的(C/C++),紧张供JVM进程内部调用,因此须要通过JDWP来实现跨进程调试。
Java Debug Interface (JDI):面向Java措辞的最高层接口,供工具开拓商快速开拓debugger程序,实现远程调试。
JDK推举利用JDI开拓debugger,从而得到java技能栈的跨平台运行能力。

JPDA架构图

debuggee: 被调试进程,包含正在被调试的运用、运行运用的VM、debugger后端Java Virtual Machine: java的调试功能终极是由VM卖力实现的。
back-end: 紧张职责是通信,把调试要求从debugger前端发送到VM,再把response返回回去。
debugger后端与前端通信是基于JDWP协议。
communication channel: debugger后端与debugger前端之间的连接,包含2个组件。
connector: 通过connector建立连接。
connector分三类:listening connector, attaching connector, launching connectortransport: 卖力底层数据交流,可以用的transport有sockets, serial lines, 和 shared memory。
front-end: 卖力实现JDI接口

JPDA只是定义了接口规范 ,须要详细实现,才能实现java调试。

Oracle JDK 针对这3个接口,供应了参考实现,详细包含:

在VM上实现了JVM TI 接口一个debugger back-end 实现(利用了JVM TI接口,实现了JDWP协议的debuggee一端)一个debugger front-end 实现(利用了JDWP协议的debugger一真个功能,实现了JDI接口)2个大略的基于JDI的调试工具,即jdb。

JDK供应的参考实现

JPDA是分层架构设计,个中的每一层都是可以更换的。
调试工具可以基于JDI开拓,也可以基于JDWP开拓,或直接基于JVM TI开拓。

Java中的调试功能的实现步骤

VM供应调试做事,例如供应API用于设置断点,取消断点,设置watch point,单步实行、查看stack frame等。
VM把调试功能封装成API,通过JVM TI接口的形式供应给调用方。
debugger后端程序通过调用JVM TI得到调试信息或设置调试动作,然后按照JDWP协议进行封装,实现远程调试。
debugger前端按照JDWP协议调用debugger后端功能,把功能封装成JDI接口。
调试工具,例如IntelliJ IDEA中的debugger,直接调用JDI实现调试功能。
4. Java虚拟机工具接口 (JVM TI)

JVM TI (Java Virtual Machine Tool Interface) 是一个本地编程接口(C++),紧张给工具开拓商利用,例如像Eclipse、IntelliJ IDEA这样的工具。
JVM TI 可以实现的功能有:

查看Java运用程序内部状态掌握Java运用程序的实行查看JVM的内部状态

通过用JVM TI来访问JVM的内部状态,可以实现各种各样的工具,例如 profiling(剖析)、debugging(调试)、monitoring(监控)、thread analysis(线程剖析) 和 coverage analysis等类型工具。

JVM的调试功能是在JVM内部实现,然后通过JVM TI接口开放给第三方工具厂商的。

JVM TI是一个双向接口。
JVM TI的客户端(也便是agent)可以利用events功能感知到JVM中发生的事宜,还可以通过functions功能来查询程序的状态和掌握程序的实行。

这个agent与JVM在同一个进程中运行,它通过直接调用JVM TI接口与JVM通信。
agent再被其余一个进程掌握,这样实现java本地调试功能。

在windows系统上,agent一样平常是一个DLL库,在类unix系统上,agent一样平常是一个so文件。

agent是在JVM启动的时候,通过命令行选项加载的,有2种加载办法:

加载办法一

-agentlib:<agent-lib-name>=<options>brbragent-lib-name 指的是agent的名称broptions是传给这个agents的选项

加载办法二

-agentpath:<path-to-agent>=<options>

JVM TI 过于靠近底层,大部分工具是通过JPDA间接访问JVM TI的。

5. 远程调试通信协议:Java Debug Wire Protocol (JDWP)

JDWP是一种实现Java运用程序远程调试的通信协议,即jvm和debugger之间实现通信,例如传输线程状态、非常信息等。

JDWP实现debuggee和debugger之间的隔离,以是debugger可跨平台运行和调试。

隔离除了可以实现跨平台的上风以外,被调试的JVM中的GC、OOM等事宜不会影响debugger自身运行。

JDWP只定义数据的格式,没有指定传输协议,只需一个大略API就可以支持多种传输办法。

JDWP大略,随意马虎实现,灵巧,便于扩展(JDWP设计考虑到了JDI的利用方便)。

JDWP Start Up(握手机制)

建立连接之后,首先要经由一次握手,然后才开始发送packet。

debugger → target vm: JDWP-Handshake

target vm → debugger: JDWP-Handshake

JDWP Packet (数据包)

packet分为2类:1. command packets 2. reply packets

debugger往target vm发送command packet,从而:1)获取信息 2)掌握程序实行

target vm往debugger发送command packet,从而:关照debugger,vm中发生的事宜(event)。

replay packet 用于关照操作是否成果和获取返回数据

Command Packet

Reply Packet

Headerlength (4 bytes)id (4 bytes)flags (1 byte)command set (1 byte)command (1 byte)data (Variable)Headerlength (4 bytes)id (4 bytes)flags (1 byte)error code (2 bytes)data (Variable)6. Java调试接口:Java Debug Interface (JDI)

JDI是JPDA架构中最高层Java API。
通过调用JDI接口可以得到debugger须要的信息,也可以掌握被调试程序的运行。

JDK通过SPI模式为JDI供应了详细实现(位于 lib/tools.jar),完全实现了JDWP协议后端部分,可以远程连接、Attach、监控和掌握target JVM。

JDI组成部分

name

desc

com.sun.jdi

core package,定义了value, type 和 虚拟机的镜像

com.sun.jdi.connect

供应debugger和target vm之间的Connector实现,实现网络连接

com.sun.jdi.connect.spi

如果JDK自带的Connector实现不能知足须要,可以通过这里的接口自定义Connector

com.sun.jdi.event

JDI中的event定义和处理工具

com.sun.jdi.request

用于实现知足特定条件就发送event

基于JDI开拓debugger步骤

1. 调用JDI中用于建立与target vm建立连接的API,创建Connector。
本地调试可以创建LaunchingConnector,远程调试可以创建AttachingConnector。

2. Connector创建好之后launch或者attach到target vm。

3. 设置event,例如ClassPrepareEvent、BreakpointRequest等:

例如设置断点可以创建BreakpointRequest

4. 断点触发之后,须要处理BreakpointEvent,例如打印所有变量

5. 综合起来

这个例子来自:www.baeldung.com/java-debug-interface

7. 基于JDI开拓debugger的示例

JDK的一个子目录(JDK demo包)即 $JDK/demo/jpda 中,有3个JDI接口的利用示例(源码和文档)。

trace:显示程序实行轨迹。
jdb:JDK中自带的命令行调试工具。
javadt:一个大略的GUI调试工具。

希望这篇文章能对您有帮助!
如果您对互联网、前/后/客户端、架构/分布式/高可用/高并发/高实时、电商、Redis、MySQL、Zookeeper、Spring、Android、浏览器插件、Java、C/C++、Linux、个性化推举、社区创造、机器学习、数据挖掘等感兴趣,欢迎关注。

标签:

相关文章

招商蛇口中国房地产龙头企业,未来可期

招商蛇口(股票代码:001979),作为中国房地产企业的领军企业,自成立以来始终秉持“以人为本,追求卓越”的经营理念,致力于打造高...

网站推广 2025-02-18 阅读1 评论0