性能工具之 Java 调试工具 JDB

举报
zuozewei 发表于 2021/08/04 21:20:23 2021/08/04
【摘要】 严格来说,JDB 是 Java 调试工具。但是为了文章好分类,所以我加了“性能工具”几个字。其实才是仅为性能工具呢,这个是不好分类的。仅有一些专门的性能测试和性能监控工具,但是对性能分析、性能调试来说,用的工具几乎都不是专门为性能而设计的。

前言

严格来说,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")) {
51 MEMTestDemo 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 中的变量值、监控某个变量的修改记录等等。

总结

不用特定死板的界定工具是用来干什么的,要看你想达到的目的是什么。包括它在什么时候用,怎么用,都没有统一的标准,就看适合不适合。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。