如何在多线程下调试线程

条件断点

  1. 条件断点调试能够方便我们在调试过程中对某个特定的线程或特定的值进行调试,在大量的循环操作或是高并发情况下的断点调试会十分的不方便,而条件断点调试可以根据的你条件对响应的代码进行调试。
    • 首先是在调试处打上断点,之后可以右键断点就会出现以下的条件输入框,或者是快捷键Ctrl+Shift+F8唤出条件输入框。
      在这里插入图片描述

java Dump

  1. 在输入命令时可能出现的问题

jps(显示java进程)

  1. jps是jdk自带的命令,其位于jdk的bin目录中;输入jps后,将列出了所有运行的进程及进程ID。
    在这里插入图片描述
  2. 当然上面提到的只是默认情况下的打印,接下来我们看看jps命令还有那些命令选项:
    在这里插入图片描述
    • 在查看之前我们先自定义一个类,再根据该类的运行信息来帮助我们学习jps的命令选项
      -
    • jps -q:该命令下只会显示进程id不会显示class信息
      在这里插入图片描述
    • jps -m:该命令会展出传入main方法的参数信息,但是注意的是在嵌入式jvm时可能为null
      在这里插入图片描述
    • jps -v:展示当前进程的jvm运行参数
      在这里插入图片描述
    • jps -l :会展示当前进程的包名加类名
      在这里插入图片描述

jstack(查看线程)

  1. jdk对线程定义的几种状态
    在这里插入图片描述
    • NEW:尚未启动的线程,该状态不会在出现在线程分析中
    • RUNNABLE:可执行的线程,可能在执行中
    • BLOCKED:线程发生阻塞,该线程在等待一个监视器锁的释放
    • WAITING:当调用object.wait()或Thread.join()或LockSupport.prak()时线程会进入等待状态
    • TIMED_WATING:线程等待指定时间,当调用object.wait(long)或Thread.join(long)或Thread.sleep(long)或LockSupport.parkNanos()或LockSupport.parkUntil()会触发线程进入该状态。
    • TERMINATED:已经结束的线程
  2. jstack中需要重点关注的关键字
    • 死锁,Deadlock
    • 等待资源,Waiting on condition
    • 等待获取监视器,Waiting on monitor entry
    • 阻塞,Blocked
    • jstack命令选项
      在这里插入图片描述
  3. 根据上图打印的jstack的命令选项,我们可以先看出jstack的命令可以在四种不同的情况下对线程进行分析:
    • 连接活动的进程,这种是最常用的情况,也是windows中支持的情况
    • 连接阻塞的进程,同上一种情况的命令使用。
    • 连接dump文件,这种方式发生在当程序因为崩溃而产生了core文件,则通过jstack命令查看崩溃原因
    • 最后一种是远程的连接服务器,通过ip对运行的线程进行分析,假如一台主机上多个远程debug服务 ,则需要指定server_id
  4. 通过jps命令我们首先找到所有在运行的java进程以及进程的id,在通过jstack查看某个java进程中的线程运行状况。我们创建另一个死锁类来测试查看对应的线程运行信息
    • jstack < pid >
      在这里插入图片描述
      首先第一个打印的线程运行信息是jvm的信息直接忽略掉,看到Thread-1和Thread-0的线程运行状况,我们看到线程状态为BLOCKED(受阻),之后我们在看到后面:
      在这里插入图片描述
      我们看到信息中直接提示了我们发现了一处死锁,并且打印了死锁所在的字节码。
    • jstack -l < pid >,与使用jstack < pid >是一样的效果也就是默认的命令选项,会打印线程信息和锁的信息。
    • jstack -F < pid >,该命令用于在jstack -l < pid >命令没有响应时,强制打印栈信息
      在这里插入图片描述
    • jstack -m < pid > 打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用
      在这里插入图片描述

jmap(查看内存)

  1. jmap命令选项见下图,之后我们看到jmap跟jstask差不多,可以通过三种不同的方式打印内存。
    在这里插入图片描述
  2. jmap < pid > ,使用该命令会打印出当前debug服务加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称
    在这里插入图片描述
  3. jmap -heap < pid > ,该命令会打印出当前进程的堆信息,并且对堆中每个分区的详细情况进行了打印:
    在这里插入图片描述在这里插入图片描述
  4. jmap -histo[:live] < pid > ,打印每个class的实例数目,内存占用,类全名信息. JVM的内部类名字开头会加上前缀”*”. 如果live子选项加上后,只统计活的对象数量
    在这里插入图片描述
    值的注意的是占用最高的是char数组,因为在java中String其本身就是一个final char[],所以我们才会看到char[]消耗了大量的内存。
  5. jmap clstats < pid >,打印所有的类加载器信息
    在这里插入图片描述
  6. jmap -dump:[live,]format=b,file=< filename > < pid > ,如下图使用hprof二进制形式(format=b),输出jvm的heap中活着内容(live)到文件(file=xxxx)
    在这里插入图片描述
  7. jmap -finalizerinfo < pid > ,打印当前待回收对象的数量,下图显示为0
    在这里插入图片描述
  8. jmap -F < pid >,一般在dump或histo无响应时强制打印每个共享对象的起始地址、映射大小以及共享对象文件,该命令下:live无效
    在这里插入图片描述
  9. jmap -J< flag > < option > < pid >,传递参数给JVM
    在这里插入图片描述

jstat(性能分析)

  1. jstat命令选项
    在这里插入图片描述
    • jstat class < pid >,对class对象数量及占用进行统计
      在这里插入图片描述
    • jstat -compiler < pid >,对编译数进行统计
      在这里插入图片描述
    • jstat -gc < pid >,打印当前进程的垃圾回收情况
      在这里插入图片描述
    • jstat -gccapacity < pid >,打印当前进程的堆内存分配情况
      在这里插入图片描述
    • jstat -gccause < pid >,打印当前进程堆内存占用情况和gc次数、耗时统计
      在这里插入图片描述
    • jstat -gcmetacapacity < pid > ,打印当前进程元数据空间内存分配情况
      在这里插入图片描述
    • jstat -gcnew < pid >,打印当前进程年轻代垃圾回收临界值和次数统计
      在这里插入图片描述
    • jstat -gcnewcapacity < pid >,打印当前进程年轻代内存分配情况
      在这里插入图片描述
    • jstat -gcold < pid >,打印当前进程老年代垃圾回收
      在这里插入图片描述
    • jstat -gcoldcapacity < pid >,打印当前进程老年代内存分配情况
      在这里插入图片描述
    • jstat -gcutil < pid >,统计当前进程堆中各部分内存使用比例情况
      在这里插入图片描述
    • jstat -printcompilation < pid >, 打印当前进程编译方法统计
      在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值