JDK自带工具堆栈分析实践

本文介绍了如何使用JDK自带的jps、jmap和jstack工具对Java应用程序进行堆栈分析和线程监控。在实践中,作者针对一个进行大量IO操作的线程,通过这些工具成功定位到问题代码所在的类和行数,展示了这些工具在排查问题时的强大能力。此外,还提到了jmap用于转储堆信息的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDK其实自带的有挺多工具可以进行对程序的相关运行JVM堆栈监控与查询。这次把自己使用JDK自带工具对程序堆栈分析过程列出来,以备自己复习和思考。我一直认为万物基于基础。把底层构造设计好,掌握好了。任凭风摧雨打,都能屹立不倒,JDK也是一样,其实官方自己设计集成了不少有用的东西。很多东西不是没有用武之地,是我们还没有遇到问题,也就没有机会使用它。所以,在有空闲时间或者想更深入了解某一领域的知识,自己可以不断拓宽自己的思维领域,脱离舒适安全区,不断学习与实践。

当我们使用IDE或者其他基于cmd/linux中java命令来运行程序时候,系统本地都会创建相关JVM运行对应的进程资源。而在JVM管理的内部,又是有很多java线程在运行与处理。最主要的一个线程,那当就是我们经常看到的main(String[] args)方法入口对应的线程啦。所以,开始对以正常运行的本地javaJVM进程进行实践玩玩,look,look。(哎,当然,自己也是一个菜鸟级别的码农,手握着这本人人都能修炼入门的Java心经,想要练成绝顶神功还有很长的路要走啊…..( ̄ε  ̄))

该次实践背景是:在当前运行的java应用中,有一个线程,进行了大量的IO操作。我的目的就是:通过jdk自带工具,把该线程找出来,定位为指定的应用中的代码块。例子参考了《JVM实践..》。
来来,看看运行的代码:

public class HoldIOMain{
   
 public static class HoldIOTask implements Runnable{
   
   @Override
   public void run(){
    while(true){
     try{
    FileOutputStream fos = new FileOutputStream(new File("temp"));
    for(int i=0;i<10000;i++){
     fos.write(i);
     fos.close();
     FileInputStream fis = new FileInputStream(new File("temp"));
     while(fis.read()!=-1); //a log of read operations.
    }
   }catch(Exception e){
   }
 }
}
}
 public static class LazyTask implements Runnable{
   
  public void run(){
   try{
        while(true){
          Thread.sleep(1000);
    }
   }catch(Exception e){}
  }

}
 public static void main(String[] args){    //四线程操作
  new Thread(new HoldIOTask()).start(); 
  new Thread(new LazyTask()).start();
  new Thread(new LazyTask()).start();
  new Thread(new LazyTask()).start();
}
}

查看当前JVM中运行进程

Jdk安装目录中bin路径下的jps命令。它的定义是:(百度百科中的,汗…)
jps位于jdk的bin目录下,其作用是显示当前系统的java进程情况,及其id号。jps相当于Solaris进程工具ps。不象"pgrep java"或"ps -ef grep java",jps并不使用应用程序名来查找JVM实例。因此,它查找所有的Java应用程序,包括即使没有使用java执行体的那种(例如,定制的启动 器)。另外,jps仅查找当前用户的Java进程,而不是当前系统中的所有进程。
具体实际操作如下:(前提是本地系统中JVM已经启动啦,其实只要涉及到java*.exe运行了就会查到信息)

[root@hadoop201 Desktop]# jps  (查看当前用户java相关所有进程号)
3204 Jps
3177 HoldIOMain

可以看到,当前用户系统中正在运行的java进程号id为3177。只要拿到进程号,后面的命令都可以基于进程号对进程处理中的各种资源都可以查询。进程是计算机进行资源调度的最小单位嘛。可以查看,系统态和用户态之间如何切换的,资源是如何处理的等等,进程这个真是各个很重要的概念。(不行,要去补补操作系统才行。。┑( ̄▽  ̄)┍)

根据进程号查看进程信息

在第一步中,我们通过jps可以找到名字为HoldIOMain的进程号为3177,之后,我们可以通过pidstat -p 3177 -d -t 1 3(linux) 命令查看在当前系统中,该进程的一些基本情况。关于pidstat命令具体使用,可以参考这片文章:这里
好了,看我如何进行操作的:

[root@hadoop201 Desktop]# pidstat -p 3177 -d -t 1 3  (通过pidstat 命令查看所有线程IO读写情况)
Linux 2.6.32-504.el6.x86_64 (hadoop201) 01/11/2017 _x86_64_(1 CPU)
04:42:44 PM      TGID       TID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
04:42:45 PM      3177         -      0.00  36792.00  18396.00  java
04:42:45 PM         -      3177      0.00      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值