天天看点

Java使用的6个JDK内建工具

0、javap

你可以给 javap(Java Class文件反编译器)传递这些有用的参数:

  • -I – 打印行数和局部变量
  • -p – 打印包括非public在内的所有类和成员信息,
  • -c – 打印方法字节码

比如在著名的“你真的懂 Classloader 吗?”演讲里,当出现 NoSuchMethodException 错误时,我们可以执行以下命令来调查这个类究竟有哪些成员方法和获取这个类所有想找的信息:

javap -l -c -p Util2

Java使用的6个JDK内建工具

当调试类内部信息或者研究随机字节码顺序时,javap 非常有用。

1、jjs

Java使用的6个JDK内建工具

jjs命令可以启动一个 JavaScript 命令终端,你可以把它当做计算器或者用随机的JS字符串测试JS的古怪用法。不要让另一个 JavaScript 谜题让你措手不及!

哈,看到刚刚发生了什么了么?但是 JavaScript 是另一个话题,只需要知道即使没有 node.js 或浏览器你也可以用jjs知道JS是怎么工作的。

2、jhat

Java堆分析工具(jhat)正如它名字描述的那样:分析dump堆信息。在下面的小例子里,我们构造了一个 OutOfMemoryError ,然后给这个 java 进程指定 -XX:+HeapDumpOnOutOfMemoryError ,这样运行时就会产生一个 dump 文件供我们分析。

  1. public class OhMyMemory { 
  2. private static Map map = new HashMap<>(); 
  3. public static void main(String[] args) { 
  4.    Runtime.getRuntime().addShutdownHook( 
  5.      new Thread() { 
  6.        @Override 
  7.        public void run() { 
  8.          try { 
  9.            System.out.println("Enter something, so I'll release the process"); 
  10.            System.in.read(); 
  11.            System.out.println("We have accumulated " + map.size() + " entries"); 
  12.          } 
  13.          catch (IOException e) { 
  14.            e.printStackTrace(); 
  15.          } 
  16.        } 
  17.      } 
  18.    ); 
  19.    for(int i = 0; i < 10000 ;i++) { 
  20.      map.put(Integer.toBinaryString(i), i); 
  21.    } 

注意,现在我们不要消耗大量的内存,只是比较早结束并在进程关闭钩子里等待不让 JVM 退出。这样就允许我们用 jmap 连接这个进程获取珍贵的内存 dump。

因此你可以用 jmap 的两个功能来实现,获取堆统计信息和触发一个堆 dump。因此,当执行:

jmap -heap 1354(这里 1354 是上面程序运行的进程号),就可以获取一个很好的内存使用统计信息:

  1. $ jstack -F -l 9153 
  2. Attaching to process ID 9153, please wait... 
  3. Debugger attached successfully. 
  4. Server compiler detected. 
  5. JVM version is 25.0-b70 
  6. Deadlock Detection: 
  7. No deadlocks found. 
  8. …. 

上面的输出虽然看起来简单,但是它包含了每个线程的状态和它当前的堆栈的信息。

jstack 非常有用,我们在日常工作中使用非常频繁,特别是我们负责启动停止应用服务器的测试引擎。测试工作往往不顺利,jstack 可以让我们知道 JVM 内部的运行状态且没有什么负面的影响。

— Neeme Praks(ZeroTurnaround资深产品工程师)

还有其它的吗?

今天我们介绍了 JDK 发行预装的超棒工具。相信我,将来某天你肯定会用到它们中的一些。所以,如果你有时间,你可以翻一翻它们的官方文档。

试着在不同的场景使用并爱上它们。

如果你想学一些超棒的非 JDK 附带的工具,可以看看 JRebel ,它可以让你马上看到代码的改动效果,还可以看到我们新的产品 XRebel ,它可以像X光眼镜一样扫描你的 web 应用。

如果你知道开发最佳实践中至关重要的小工具,在本文末尾发表评论或者在 twitter上@shelajev 分享一下这个工具的细节。

Bonus Section: References

奖励环节:参考

下面是一个更加完整的 JDK 工具可用列表。虽然这不是一个完整的列表,为了节省篇幅,我们省掉了加密、web-services 相关的工具等。谢谢 manpagez.com 提供的资源。

  • jar — 一个创建和管理 jar 文件的工具。
  • java — Java 应用启动器。在这篇文章里,开发和部署都是用的这个启动器。
  • javac — Java 编译器。
  • javadoc — API 文档生成器。
  • javah — native 本地方法中用于生成 C 语言头文件和源文件。
  • javap — class 文件反编译器。
  • jcmd — JVM 命令行诊断工具,可发送诊断命令请求到 JVM 中。
  • jconsole — 一个兼容 JMX 的监控 JVM 的图形化工具。可以监控本地和远程 JVM,也可以监控和管理单独的一个应用。
  • jdb — Java 调试器。
  • jps — JVM 进程查看工具,列出了系统运行的所有 hotspot JVM 进程。
  • jstat — JVM 状态监控工具。它可以收集和打印指定的 JVM 进程性能状态。
  • jhat — 堆 dump 信息的浏览器,启动一个 web 服务器来显示你用诸如 jmap -dump 得到的堆 dump 信息。
  • jmap — Java 内存映射工具,打印指定进程、核心文件、远程调试服务器共享内存映射或者堆内存详细信息。
  • jsadebugd — Java 服务调试守护进程—依附到一个 Java 进程或核心文件并且担当一个调试服务器的作用。
  • jstack —Java 堆栈信息工具——打印指定进程或核心文件或者远程调试服务器的线程堆栈。
  • jjs — 运行 Nashorn 命令行脚本 shell。
  • jrunscript — Java 脚本运行工具。不过你要心里有数,这实际上是一个还没支持的测试功能。未来的 JDK 版本里面可能会移除它。