- 浏览: 987475 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
运乃强谦:
老哥,你确定这个wsdl 地址 可以访问?
[CXF] Server与Client实现方式五:HTTPS -
wangyudong:
由CXF实现的微服务需要有比较好的工具去测试RESTful A ...
[CXF] Server与Client实现方式四:JMS -
dengmiao:
JAXB学习三 (验证) -
panamera:
你好。可以提供maven pom配置是怎么配置的?不知道你使用 ...
[CXF] Server与Client实现方式四:JMS -
u010221220:
请问楼主一二三部分的代码都应该放在哪个函数体中。
使用JDI监听Java程序运行
Java虚拟机提供了一套用于调试(JVMDI)和监视(JVMPI)的接口,Java5之后统一为JVMTI: http://docs.oracle.com/javase/1.5.0/docs/guide/jvmti/ 。
其中JVMDI分为三个部分:JVMDI,JDWP和JDI . http://docs.oracle.com/javase/1.4.2/docs/guide/jpda/architecture.html
这篇就是简单的介绍一下怎么使用JDI去监视程序的运行的。
首先假设有一个简单的程序:
package test; public class Test { public static void main(String[] args) { new Thread() { @Override public void run() { Test test = new Test(); while (true) { try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } test.printHello(); } } }.start(); } protected void printHello() { System.out.println("hello"); } }
程序中,每隔五秒种,printHello()方法就会执行一次。
如果你希望每次printHell()被执行的时候通知你一下,在不修改代码的情况下,你要怎么办?没办法吧?
看看JDI的定义:
JDI - Java Debug Interface Defines a high-level Java language interface which tool developers can easily use to write remote debugger applications.
所以首先,我们先以远程调试的方式启动上面的Test类:
java -Xdebug -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8800 -cp . test.Test
大致就是以socket传输的方式调试Test类,调试的连接端口为8800,并且连接过程不挂起。
一量启动,就可以看到如下的输出:
Listening for transport dt_socket at address: 8800 hello hello hello
这样Server被调试端就准备好了,下面就是写监听端了。这里就要用到jdk中提供的JDI接口了。要使用此接口,我们需要在类路径里包含JDK下的tools.jar等包,可以在<JDK>/lib目录下找着。
一、取得连接器
VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); List<AttachingConnector> connectors = vmm.attachingConnectors(); SocketAttachingConnector sac = null; for (AttachingConnector ac : connectors) { if (ac instanceof SocketAttachingConnector) { sac = (SocketAttachingConnector) ac; break; } } if (sac == null) { System.out.println("JDI error"); return; }
二、连接到远程虚拟器
Map arguments = sac.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(String.valueOf(8800)); vm = sac.attach(arguments);
三、取得要关注的类和方法
List<ReferenceType> classesByName = vm.classesByName("test.Test"); if (classesByName == null || classesByName.size() == 0) { System.out.println("No class found"); return; } ReferenceType rt = classesByName.get(0); List<Method> methodsByName = rt.methodsByName("printHello"); if (methodsByName == null || methodsByName.size() == 0) { System.out.println("No method found"); return; } Method method = methodsByName.get(0);
四、注册监听
vm.setDebugTraceMode(VirtualMachine.TRACE_EVENTS); vm.resume(); EventRequestManager erm = vm.eventRequestManager(); MethodEntryRequest methodEntryRequest = erm.createMethodEntryRequest(); methodEntryRequest.addClassFilter(rt); methodEntryRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE); methodEntryRequest.enable(); BreakpointRequest breakpointRequest = erm .createBreakpointRequest(method.location()); breakpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); breakpointRequest.enable(); eventLoop();
这里监听每次方法入口的时候,以及在方法上注册一个断点,发一个通知。
四、eventLoop()的实现
private static void eventLoop() throws Exception { eventQueue = vm.eventQueue(); while (true) { if (vmExit == true) { break; } eventSet = eventQueue.remove(); EventIterator eventIterator = eventSet.eventIterator(); while (eventIterator.hasNext()) { Event event = (Event) eventIterator.next(); execute(event); } } } private static void execute(Event event) throws Exception { if (event instanceof VMStartEvent) { System.out.println("VM started"); eventSet.resume(); } else if (event instanceof BreakpointEvent) { System.out .println("Reach Method printHello of test.Test"); eventSet.resume(); } else if (event instanceof MethodEntryEvent) { MethodEntryEvent mee = (MethodEntryEvent) event; Method method = mee.method(); System.out.println(method.name() + " was Entered!"); eventSet.resume(); } else if (event instanceof VMDisconnectEvent) { vmExit = true; } else { eventSet.resume(); } }
最后看输出:
[JDI: EventSet: SUSPEND_EVENT_THREAD] [JDI: Event: MethodEntryEvent@test.Test:23 in thread Thread-0] [JDI: Event: BreakpointEvent@test.Test:23 in thread Thread-0] printHello was Entered! Reach Method printHello of test.Test [JDI: EventSet: SUSPEND_EVENT_THREAD] printHello was Entered! [JDI: Event: MethodEntryEvent@test.Test:23 in thread Thread-0] [JDI: Event: BreakpointEvent@test.Test:23 in thread Thread-0] Reach Method printHello of test.Test
发表评论
-
自定义Spring MVC中的数据绑定
2015-02-01 18:27 1489默认情况下,spring mvc的数据映射的实现是自动查找请 ... -
Java单例(Singleton)
2014-05-22 11:40 1902【译自:http://www.journaldev.com ... -
Java函数式编程学习二
2014-06-05 10:58 2665上一节里,介绍了一个函数接口: java.uti ... -
Java函数式编程学习一
2014-05-07 22:02 7339一、缺省方法 首先看一段用Java 8写的代码: ... -
快速排序的几种实现
2014-05-06 23:13 1677快速排序是最经典的 ... -
计算Fibonacci数列
2014-05-04 15:37 1657Fibonacci数列的定义如 ... -
(转)Java函数式编程系列文章
2014-04-11 16:52 744转载: Java函数式编程(一) Java函数式编程( ... -
Java中的动态代理
2014-04-02 15:11 2352在使用CXF的时候,尤其是创建针对REST或SOAP服务的 ... -
Java 7中的Path
2014-04-01 17:33 0package test; public ... -
HashMap对HashTable和ArrayList对Vector
2014-03-26 14:16 847有人面试总喜欢问比 ... -
Java国际化:BreakIterator
2014-03-21 11:51 2972【译自:http://tutorials.jenkov.c ... -
Java中使用StreamTokenizer
2014-03-21 09:44 3314按照Javadoc里的描述:StreamTokenizer ... -
Java中枚举的用法
2014-03-19 15:31 2797Java 5里新引用了枚举类型,这篇文章简单介绍一下它的基 ... -
Java线程类三
2014-03-06 11:18 1140一、Callable 最早创建线程要么是通过实现Runn ... -
Java线程类二
2014-03-05 14:21 1192一、java.util.concurrent.Exchan ... -
Java线程类一
2014-03-04 17:25 950一、java.util.concurrent.CountD ... -
基于Java的Dropbox文件操作
2014-01-22 11:15 4326Dropbox提供了基于各种类型的API和应用类型的开发工 ... -
使用特殊字符控制Console输出
2013-11-28 10:39 1061如果要在console上打印 Hello + 1到10,最简 ... -
控制JAXB的输入输出
2013-11-27 16:06 4137上一节介绍了如何在解析模型的时候构建模型之间的父子链,其实 ... -
JAXB中怎么构建对父对象的链接
2013-11-27 11:17 3592还是以在第一节介绍JAXB的schema为例: < ...
相关推荐
本篇文章将深入探讨如何使用Eclipse进行远程调试Java应用程序。 首先,确保你已经安装了Eclipse的最新版本,例如Ganymede(V3.4)。Ganymede引入了套接字监听连接器,使得远程调试变得更加灵活。在创建启动配置时,...
远程调试是指在一个主机上调试运行在另一台机器上的应用程序的技术。这对于分布式系统的开发尤其有用,因为它允许开发者在不同的环境中调试代码,确保应用能够正确地在目标环境中运行。 #### 二、配置步骤 ##### 1...
综上所述,JPDA是Java开发中不可或缺的调试框架,通过深入学习其原理和实践,开发者可以更好地理解和控制Java应用程序的运行,提升问题排查和优化的能力。在提供的博客链接中,你可以找到更多关于JPDA的实战经验和...
2. **效率提升**:无需反复打包、部署即可实时查看程序运行状态,极大提高了开发效率。 3. **问题快速定位**:特别是在微服务架构下,远程调试可以帮助开发人员快速定位故障服务,减少故障排查时间。 4. **团队协作*...
JPDA提供了一套标准接口,使得调试工具能够与正在运行的Java应用程序交互。该架构主要由以下几个部分组成: - **Java虚拟机工具接口 (JVMTI)**:提供了对虚拟机内部操作的低级别访问,包括线程状态、类加载等。 - *...
这需要与Java的调试接口(如JDI - Java Debug Interface)交互,允许开发者在运行时检查程序状态,这对于学习和优化代码非常有用。 6. **文件操作** 文本编辑器还需要支持打开、保存和另存为文件的功能。这涉及...
5. **JDI**:调试客户端使用的一组 Java 接口。 #### 三、JVM 调试参数详解 为了以调试模式启动 JVM,可以使用以下参数: - `-Xdebug`:启用调试支持。 - `-Xnoagent`:不使用默认的代理。 - `-Xrunjdwp:...
Polish是一种用于创建J2ME(Java 2 Micro Edition)应用的开发工具包,它提供了高级的编程接口和优化机制,使得开发者能够编写出运行速度快、内存占用小的应用程序。由于其特殊的编译和运行机制,在调试过程中会遇到...
JDK参数详解:在Java开发中,理解并正确使用JDK参数对于优化应用程序性能、排查问题至关重要。本文将重点讲解如何利用JDK的JPDA(Java Platform Debugger Architecture)接口来解决特定问题,特别是如何在Weblogic...
本压缩包"debug-changebreakpoint.rar"涉及的核心知识点是调试(debug)和断点(breakpoint)管理,这对于理解和优化Java程序的运行至关重要。我们将深入探讨这两个概念,并结合提供的"debug-changebreakpoint.js"文件...
Eclipse的调试功能依赖于Java Debug Interface (JDI),它是Java Development Kit (JDK)的一部分。确保你已经安装了最新版本的JDK,并且Eclipse也配置了正确的JDK路径。 步骤1:导入jar包到Eclipse 要调试jar包中的...
远程调试使得开发者可以在本地IDEA环境中调试运行在远程服务器上的应用程序,这对于分布式系统或者大型项目的开发尤其有用。下面将详细介绍IDEA实现远程调试的步骤。 **一、远程调试基本原理** 远程调试的核心在于...