今天在整理PPT的时候,发现没有这个工具的slide,所以就随手整理一下。
严格来说,JDB是JAVA调试工具。但是为了文章好分类,所以我加了“性能工具”几个字。其实才是仅为性能工具呢,这个是不好分类的。仅有一些专门的性能测试和性能监控工具,但是对性能分析、性能调试来说,用的工具几乎都不是专门为性能而设计的。
我们知道windows上面有windebug,Linux上面有GDB,在java的层面呢就有jdb可以用了。
它可以实现对java进程和线程进行各种动态控制操作。命令参数可以在网上查查或者直接help一下。由于太长,我就不列在这里了。直接把我的操作列在这里供参考。
服务端:
在要运行的java程序中的JAVA_OPTIONS里加入:-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y
看需要,suspend可以为n,也就是不等待连上来就直接运行程序。这个和jprofiler连接中的参数是一个意思。
客户端:
localhost:~Zee$?jdb-attach 192.168.1.105:8000 -sourcepath?
/Users/Zee/Documents/workspace/testProj/src/??#连接远程JVM,带源代码
Setuncaught java.lang.Throwable
Setdeferred uncaught java.lang.Throwable
Initializingjdb ...
>?
VMStarted: No frames on the current call stack
main[1]threads??#查看线程
Groupsystem:
?(java.lang.ref.Reference$ReferenceHandler)0x153 Reference Handler cond.waiting
?(java.lang.ref.Finalizer$FinalizerThread)0x152? Finalizer???????? cond. waiting
? (java.lang.Thread)0x151???????????????????????? Signal Dispatcherrunning
Groupmain:
? (java.lang.Thread)0x1?????????????????????????? main????????????? running
>?stop atZee.MemoryTest.OOM.MEMTestDemo:42??#设置断点
Setbreakpoint Zee.MemoryTest.OOM.MEMTestDemo:42
>????#断点命中
Breakpoint hit: "thread=main",Zee.MemoryTest.OOM.MEMTestDemo.main(), line=42 bci=6
42if(args[0].equals("HeapOOM")) {
>?thread0x1??#进入线程
main[1]where??#查看位置
? [1] Zee.MemoryTest.OOM.MEMTestDemo.main(MEMTestDemo.java:42)
Localvariables:
main[1]clear??#查看断点
Breakpointsset:
? breakpoint Zee.MemoryTest.OOM.MEMTestDemo:42
main[1]cont??#继续执行
>where
Nothread specified.
>thread 0x1
main[1]suspend??#暂停线程
Allthreads suspended.
main[1]where??#查看位置??
? [1] Zee.MemoryTest.OOM.MEMTestDemo.main(MEMTestDemo.java:46)
main[1]tracemethods 0x1??#跟踪方法调用
main[1]
main[1]cont
>?
Methodentered:?
Methodentered: "thread=main", Zee.MemoryTest.OOM.OOMObject.<init>(),line=3 bci=0
3??? public class OOMObject {
main[1]untracemethods 0x1??#取消跟踪
main[1]step??#单步调试
>?
Stepcompleted: "thread=main", Zee.MemoryTest.OOM.MEMTestDemo.main(),line=46 bci=33
46??? ? list.add(newOOMObject());
main[1]next??#执行一行(stepOVERCalls)
>?
Stepcompleted: "thread=main", Zee.MemoryTest.OOM.MEMTestDemo.main(),line=45 bci=39
45while (true) {
main[1]locals??#查看变量
Methodarguments:
args= instance of java.lang.String[1] (id=439)
Localvariables:
list= instance of java.util.ArrayList(id=441)
main[1]list??#查看源码
42??? ? if(args[0].equals("HeapOOM")) {
43??? ? List<OOMObject>list = new ArrayList<OOMObject>();
44????
45??? ? while(true) {
46=> ? list.add(new OOMObject());
47??? ? }
48??? ? }
49????
50??? ? if(args[0].equals("StackSOF")) {
51MEMTestDemo memtestdemo = newMEMTestDemo();●
main[1]dumplist??#dump变量
?list = {
??? serialVersionUID: 8683452581122892189
??? DEFAULT_CAPACITY: 10
??? EMPTY_ELEMENTDATA: instance ofjava.lang.Object[0] (id=442)
??? DEFAULTCAPACITY_EMPTY_ELEMENTDATA: instanceof java.lang.Object[0] (id=443)
??? elementData: instance ofjava.lang.Object[2734845] (id=444)
??? size: 1964611
??? MAX_ARRAY_SIZE: 2147483639
??? java.util.AbstractList.modCount: 1964611
???java.util.AbstractCollection.MAX_ARRAY_SIZE: 2147483639
}
其实JDB还可以做更多的事情,比如说修改JVM中的变量值、监控某个变量的修改记录等等。
不用特定死板的界定工具是用来干什么的,要看你想达到的目的是什么。包括它在什么时候用,怎么用,都没有统一的标准,就看适合不适合。