Java工具-使用JDK自带工具查看字节码指令和线程运行状态

一、使用javap反编译查看字节码指令

第一步:找到我们要反编译的类的.class文件所在的位置,我学习Concurrence的代码的class全部放在D:\Java_Program\JavaBasic\out\production\JavaBasic\Concurrence。
这里写图片描述
第二步:复制上面的路径,进入Power Shell中(Win7是cmd中,我的是Win10)

PS C:\WINDOWS\system32> cd D:\Java_Program\JavaBasic\out\production\JavaBasic\Concurrence
PS D:\Java_Program\JavaBasic\out\production\JavaBasic\Concurrence>

第三步:运行下面的命令和你需要反编译的class文件名,

PS D:\Java_Program\JavaBasic\out\production\JavaBasic\Concurrence> javap -c SleepAndWait

第四步:得到反编译的二进制文件结果

警告: 二进制文件SleepAndWait包含Concurrence.SleepAndWait
Compiled from "SleepAndWait.java"
public class Concurrence.SleepAndWait {
  public Concurrence.SleepAndWait();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/Thread
       3: dup
       4: new           #3                  // class Concurrence/Thread1
       7: dup
       8: invokespecial #4                  // Method Concurrence/Thread1."<init>":()V
      11: invokespecial #5                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
      14: invokevirtual #6                  // Method java/lang/Thread.start:()V
      17: ldc2_w        #7                  // long 5000l
      20: invokestatic  #9                  // Method java/lang/Thread.sleep:(J)V
      23: goto          31
      26: astore_1
      27: aload_1
      28: invokevirtual #11                 // Method java/lang/InterruptedException.printStackTrace:()V
      31: new           #2                  // class java/lang/Thread
      34: dup
      35: new           #12                 // class Concurrence/Thread2
      38: dup
      39: invokespecial #13                 // Method Concurrence/Thread2."<init>":()V
      42: invokespecial #5                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
      45: invokevirtual #6                  // Method java/lang/Thread.start:()V
      48: return
    Exception table:
       from    to  target type
          17    23    26   Class java/lang/InterruptedException
}

如果我们想要得到更详细的信息,可以运行下面的命令(推荐使用)

PS D:\Java_Program\JavaBasic\out\production\JavaBasic\Concurrence> javap -verbose SleepAndWait

反编译得到的信息

警告: 二进制文件SleepAndWait包含Concurrence.SleepAndWait
Classfile /D:/Java_Program/JavaBasic/out/production/JavaBasic/Concurrence/SleepAndWait.class
  Last modified 2018-7-28; size 798 bytes
  MD5 checksum 7f5f4f64266bcbfe4ac1d2f452c8ade1
  Compiled from "SleepAndWait.java"
public class Concurrence.SleepAndWait
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #15.#33        // java/lang/Object."<init>":()V
   #2 = Class              #34            // java/lang/Thread
   #3 = Class              #35            // Concurrence/Thread1
   #4 = Methodref          #3.#33         // Concurrence/Thread1."<init>":()V
   #5 = Methodref          #2.#36         // java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
   #6 = Methodref          #2.#37         // java/lang/Thread.start:()V
   #7 = Long               5000l
   #9 = Methodref          #2.#38         // java/lang/Thread.sleep:(J)V
  #10 = Class              #39            // java/lang/InterruptedException
  #11 = Methodref          #10.#40        // java/lang/InterruptedException.printStackTrace:()V
  #12 = Class              #41            // Concurrence/Thread2
  #13 = Methodref          #12.#33        // Concurrence/Thread2."<init>":()V
  #14 = Class              #42            // Concurrence/SleepAndWait
  #15 = Class              #43            // java/lang/Object
  #16 = Utf8               <init>
  #17 = Utf8               ()V
  #18 = Utf8               Code
  #19 = Utf8               LineNumberTable
  #20 = Utf8               LocalVariableTable
  #21 = Utf8               this
  #22 = Utf8               LConcurrence/SleepAndWait;
  #23 = Utf8               main
  #24 = Utf8               ([Ljava/lang/String;)V
  #25 = Utf8               e
  #26 = Utf8               Ljava/lang/InterruptedException;
  #27 = Utf8               args
  #28 = Utf8               [Ljava/lang/String;
  #29 = Utf8               StackMapTable
  #30 = Class              #39            // java/lang/InterruptedException
  #31 = Utf8               SourceFile
  #32 = Utf8               SleepAndWait.java
  #33 = NameAndType        #16:#17        // "<init>":()V
  #34 = Utf8               java/lang/Thread
  #35 = Utf8               Concurrence/Thread1
  #36 = NameAndType        #16:#44        // "<init>":(Ljava/lang/Runnable;)V
  #37 = NameAndType        #45:#17        // start:()V
  #38 = NameAndType        #46:#47        // sleep:(J)V
  #39 = Utf8               java/lang/InterruptedException
  #40 = NameAndType        #48:#17        // printStackTrace:()V
  #41 = Utf8               Concurrence/Thread2
  #42 = Utf8               Concurrence/SleepAndWait
  #43 = Utf8               java/lang/Object
  #44 = Utf8               (Ljava/lang/Runnable;)V
  #45 = Utf8               start
  #46 = Utf8               sleep
  #47 = Utf8               (J)V
  #48 = Utf8               printStackTrace
{
  public Concurrence.SleepAndWait();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LConcurrence/SleepAndWait;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=2, args_size=1
         0: new           #2                  // class java/lang/Thread
         3: dup
         4: new           #3                  // class Concurrence/Thread1
         7: dup
         8: invokespecial #4                  // Method Concurrence/Thread1."<init>":()V
        11: invokespecial #5                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
        14: invokevirtual #6                  // Method java/lang/Thread.start:()V
        17: ldc2_w        #7                  // long 5000l
        20: invokestatic  #9                  // Method java/lang/Thread.sleep:(J)V
        23: goto          31
        26: astore_1
        27: aload_1
        28: invokevirtual #11                 // Method java/lang/InterruptedException.printStackTrace:()V
        31: new           #2                  // class java/lang/Thread
        34: dup
        35: new           #12                 // class Concurrence/Thread2
        38: dup
        39: invokespecial #13                 // Method Concurrence/Thread2."<init>":()V
        42: invokespecial #5                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
        45: invokevirtual #6                  // Method java/lang/Thread.start:()V
        48: return
      Exception table:
         from    to  target type
            17    23    26   Class java/lang/InterruptedException
      LineNumberTable:
        line 5: 0
        line 8: 17
        line 11: 23
        line 9: 26
        line 10: 27
        line 12: 31
        line 13: 48
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           27       4     1     e   Ljava/lang/InterruptedException;
            0      49     0  args   [Ljava/lang/String;
      StackMapTable: number_of_entries = 2
        frame_type = 90 /* same_locals_1_stack_item */
          stack = [ class java/lang/InterruptedException ]
        frame_type = 4 /* same */
}
SourceFile: "SleepAndWait.java"

使用jstack可以查看线程信息

### 如何在 Windows 系统中运行 Java 项目 要在 Windows 上成功运行 Java 项目,可以按照以下方法操作: #### 配置环境变量 为了能够在命令行或其他工具中调用 `javac` `java` 命令,需要先配置好系统的 JAVA_HOME 变量以及将其加入到 PATH 中[^1]。 ```batch set JAVA_HOME=C:\Program Files\Java\jdk-version set PATH=%JAVA_HOME%\bin;%PATH% ``` 上述脚本会设置 JDK 的安装路径并更新系统 PATH。完成后可以在任意目录通过输入 `java -version` 来验证是否正确设置了环境变量。 #### 编写简单的 HelloWorld 程序作为测试案例 创建一个新的 `.java` 文件名为 `HelloWorld.java` 并编写如下代码: ```java public class HelloWorld { public static void main(String[] args){ System.out.println("Hello, world!"); } } ``` 保存文件之后,在同一目录打开命令提示符 (CMD),编译该源码文件: ```batch javac HelloWorld.java ``` 如果没有任何错误发生,则会产生一个对应的字节码文件即 `HelloWorld.class` 。接着可以通过下面这条指令来执行它: ```batch java HelloWorld ``` 这将会打印出 “Hello, world!” 到控制台输出流上表示整个流程顺利完成。 对于更复杂的项目或者已经打包成 JAR 格式的应用程序来说,可能还需要指定额外参数比如内存分配大小等信息给 JVM 虚拟机实例化时使用。例如这样一条完整的启动语句可用于某些特定场景下的应用加载需求: ```batch java -Djava.class.path=your-application.jar;"%JAVA_HOME%"\lib\tools.jar -Xms64M -Xmx512M com.example.MainClassArgumentHere arg1 arg2 ... ``` 这里 `-D`, `-Xms`, `-Xmx` 参数分别代表定义属性、初始堆大小与最大可用堆空间;而最后部分则是指明主类全限定名及其后续跟随的实际业务逻辑所需传递进去的数据项列表[^4]。 另外值得注意的是有时候我们希望让某个长期运行的服务型 java 应用能够脱离当前终端保持独立运作状态而不受人为干扰影响——这就涉及到如何实现后台无窗口模式下持续运转的技术手段了。一种常见做法就是利用 windows 自带的任务计划器配合批处理脚本来完成自动化部署工作。另一种相对简便的方式则是在原始 cmd 启动命令前加上 start /B 关键词即可达成目的效果[^2]: ```batch start /B "" java YourMainClass ``` 最后当遇到性能监控调试方面的需求时候还可以借助专门开发出来的图形界面管理工具像 VisualVM 或者 JConsole 它们能帮助开发者直观地观察正在活动中的各个线程状况以及其他重要指标数据变化趋势从而更好地优化调整现有架构设计缺陷之处[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值