JVM 问题定位工具

VisualVMJDB

JDB 是基于文本和命令行的调试工具,Jikes 在 JDB 的基础上提供了 GUI。熟悉 JDB 还是有价值的,很多情况下需要我们在命令行下完成简单的 debug 问题定位。

jdb -classpath bin com.xx.Example
jdb -connect com.sun.jdi.SocketAttach:hostname=myhost,port=8000
jdb -connect "com.sun.jdi.CommandLineLaunch:main=Hello 1 2 3"

我们可能更熟悉使用下面这样的方式来进行调试,但本质上就是在使用 JDB:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9000

很多人都知道使用它可以连接上 JVM 进行远程调试,但是并不清楚这些参数的含义都是什么。那么你可以阅读一下 JPDA 的文档,JPDA 是一种用于虚拟机和调试器之间消息传输的方式,二者谁都可以成为 server,另一者则成为 client。Sun 发布了两种实现,一种是基于 TCP/IP 的(Socket 传输),另一种是基于共享内存的(共享内存传输)。

  • Socket 传输:这也是我们最常用的调试方式,其中的命令定义和响应包的定义请参阅这两个文档 JDWP 规格JDWP 传输接口 。这就是参数中 transport=dt_socket 的含义。
  • 共享内存传输:参数需要改成 transport=dt_shmem。这种模式只支持 Windows 平台,当然,客户端和服务端当然在一台机器上。

Sun 虚拟机实现需要指定命令行选项,以加载 JDWP(Java Debug Wire Protocol Transport)代理来 debug。JDK 5.0 以前需要指定-Xdebug 和-Xrunjdwp 这两个参数,以后则可以使用参数-agentlib:jdwp 替代之,它们指定了 JVM 使用的连接器。从上面的例子代码可以看到几个 jdwp 支持的参数选项,包括 transport、server、suspend、address 等等,这些都很常见,还包括 timeout、launch(中断并开始调试的时候,执行什么程序)、onuncaught(如果出现无法捕获的异常是否需要中断并调试)等等。

-agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub

这段参数是说,在抛出 IO 异常时,中断并执行 debugstub。

早些时候 JVM 曾经因为开放这样的 debug 端口,遇到远程扫描,虚拟机发生崩溃,参见 bug 链接

VisualVM 和 JConsole

VisualVM 这个工具来自 Netbeans 的项目,JVM 的运行情况一目了然。它已经被收录到 JDK 的官方工具中去了,官网 上面可以找到很多插件,这是这个工具尤其出色的地方。

JConsole 也集成在 JDK 的工具中,图形化地监视虚拟机的状态。

jinfo/jmap/jhat/jstack/jstat

这几个命令行工具可以很方便地查看当前虚拟机的参数信息、堆、内存图、线程堆栈和垃圾回收信息,它们非常常用,不需要预先使用参数增加虚拟机开启的端口。其中,jhat 命令尤其强大,它可以把堆中的对象导出成为 html 文件,比较两次虚拟机快照的不同,同时还支持对象查询语句来查询堆中对象的状态。

JProfiler 和 Optimizeit

JProfilerOptimizeit 一样,都是综合性的性能剖析工具,甚至可以分析不同方法的 CPU 时间占用,帮助找出 CPU 热点。

GCView,HP Jmeter,Garbage Cat 和 GC Analyzer

这几个是 GC 日志分析工具。

IBM HeapAnalyzer 和 MemoryAnalyzer

IBM HeapAnalyzerMemoryAnalyzer 都是 dump 文件分析工具,可以观察不同对象的数量,对象之间的引用关系等等,可以协助发现内存泄露点。说明一下,我们需要把 core 文件和 dump 文件区分清楚。dump 文件是堆内存的映像信息,相当于把内存中存放的对象映射到一个文件里,这个文件通常会比较大;而 core 文件是当前的线程栈信息,是可以使用 kill -3 命令生成的,也可以使用 jstack 命令获取。

BTrace

Btrace 是一种安全和动态的跟踪分析工具,功能非常强大,可以动态分析 Java 程序是怎么执行的。原理是在运行时把系统中的某些类替换成包含跟踪代码的类(字节码跟踪),而跟踪代码也是用 Java 语言完成的。

总的来说,通常监控型的工具功能最强大,但是对系统资源要求也很高,对于生产环境上特有的问题,还是多考虑使用一些快照工具,内存和 CPU 占用小,系统中断时间短。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

11,692 次阅读

发表评论

电子邮件地址不会被公开。

back to top