HouseMD, 比BTrace更实用的Java运行诊断工具
?
jar入门启动注意: 在 Mac OSX下, 选项
-Xbootclasspath
是不需要的.
假定你在?快速安装并将安装路径加入PATH?之后, 在命令行输入:
> housemd -h
你会看到HouseMD
的帮助信息, 如下:
Usage: housemd [OPTIONS] pid a runtime diagnosis tool of JVM.Options: -h, --help show help infomation of this command. -p, --port=[INT] set console local socket server port number. default: 54321Parameters: pid id of process to be diagnosing.
真正要用起来, 则需要拿到你要诊断的java
进程的ID
(通过jps
或ps
), 假设pid
是1234
, 然后执行:
> housemd 1234
帮助在显示若干行INFO
信息后, 此时进入HouseMD
的Shell
提示符, 键入help
指令, 可以查看其支持的内置指令:
housemd> helpquit terminate the process.help display this infomation.trace display or output infomation of method invocaton.loaded display loaded classes information.
在help
后加上指令的名字, 如loaded
, 便会显示具体指令的帮助信息:
housemd> help loadedUsage: loaded [OPTIONS] name display loaded classes information.Options: -h, --classloader-hierarchies display classloader hierarchies of loaded class.Parameters: name class name without package name.
退出退出支持三种方式:
quit
指令Ctrl + D
Ctrl + C
点击这里查看
指令范例loaded
housemd> loaded Stringjava.lang.String -> /usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/rt.jar
查看类
java.lang.String
的加载路径
housemd> loaded -h ScalaObjectscala.ScalaObject -> /home/housemd/housemd.jar - com.github.zhongl.housemd.Duck$1@1e859c0 - sun.misc.Launcher$AppClassLoader@1cde100 - sun.misc.Launcher$ExtClassLoader@16f0472
查看类
scala.ScalaObject
的加载路径和类加载器层次.注意: BootClassLoader由于不是
Java
语言实现, 所以不会显示.
trace
housemd> trace -t 2 TraceTarget$A.mINFO : probe class TraceTarget$ATraceTarget$A.m(int, String) TraceTarget$CL@42719c 0 -ms nullTraceTarget$A.m(String) TraceTarget$CL@42719c 2 3ms TraceTarget$A@401369TraceTarget$A.m(int, String) TraceTarget$CL@42719c 0 -ms nullTraceTarget$A.m(String) TraceTarget$CL@42719c 4 1ms TraceTarget$A@401369INFO : Ended by timeoutINFO : reset class TraceTarget$A
跟踪接下来2秒内
TraceTarget$A.m
方法的调用每列的含义依次是: 方法全名(含参数列表), 当前类的加载器对象, 总计调用次数, 平均调用耗时, 调用的自身对象
housemd> trace -l 4 TraceTarget$D+.mD1INFO : probe class TraceTarget$DTraceTarget$D.mD1(int) TraceTarget$CL@42719c 2 <1ms TraceTarget$B@80cac9INFO : Ended by overlimitINFO : reset class TraceTarget$D
跟踪接下来4次抽象类
TraceTarget$D
的mD1
方法的调用这里可以看到, 这个方法调用的触发对象是其实现类
TraceTarget$B
的实例
housemd> trace -i 4 TraceTarget$D+INFO : probe class TraceTarget$DINFO : probe class TraceTarget$BTraceTarget$B.mC(String) TraceTarget$CL@42719c 8 <1ms TraceTarget$B@80cac9TraceTarget$B.mD2(int, int) TraceTarget$CL@42719c 8 <1ms TraceTarget$B@80cac9TraceTarget$D.mD1(int) TraceTarget$CL@42719c 8 <1ms TraceTarget$B@80cac9TraceTarget$B.mC(String) TraceTarget$CL@42719c 16 <1ms TraceTarget$B@80cac9TraceTarget$B.mD2(int, int) TraceTarget$CL@42719c 16 <1ms TraceTarget$B@80cac9TraceTarget$D.mD1(int) TraceTarget$CL@42719c 16 <1ms TraceTarget$B@80cac9INFO : Ended by timeoutINFO : reset class TraceTarget$DINFO : reset class TraceTarget$B
跟踪抽象类
TraceTarget$D
所有方法的调用, 设定每隔4秒进行一次实时摘要显示, 直至默认结束条件达成
housemd> trace -d TraceTarget.addOne TraceTarget$A......
跟踪
TraceTarget.addOne
方法和?TraceTarget$A
的所有方法的调用, 并输出详细日志到文件文件的路径, 请通过
help trace
?查看-d
选项的说明获知
输出的detail
文件内容:
2012-06-14 14:38:29 8ms [main] null TraceTarget.addOne [0] 12012-06-14 14:38:29 2ms [main] TraceTarget$A@995a79 TraceTarget$A.m [123] void2012-06-14 14:38:30 0ms [main] null TraceTarget.addOne [0] 12012-06-14 14:38:30 0ms [main] TraceTarget$A@995a79 TraceTarget$A.m [123] void
日志每行以一个空格分隔, 每列的含义依次是: 日期, 时间戳, 调用耗时, 调用线程名, 调用方法的自身对象, 调用方法全名, 调用方法参数值列表, 返回值(或异常)
housemd> trace -s TraceTarget.addOne......
跟踪
TraceTarget.addOne
方法, 并输出其调用栈到文件文件的路径, 请通过
help trace
?查看-s
选项的说明获知
输出的stack文件内容:
TraceTarget.addOne(Integer) call by thread [main] TraceTarget.main(TraceTarget.java:42)
更多信息请见常见问题解答, 或指令帮助
历史版本和未来规划点击这里查看
疑问, 建议, 缺陷欢迎任何疑问, 建议还有缺陷, 请至这里提交给我.
?
后记HouseMD
是基于字节码技术的诊断工具, 因此除了Java
意外, 任何最终以字节码形式运行于JVM
之上的语言,?HouseMD
都支持对它们进行诊断, 如Clojure
(感谢@Killme2008提供了它的使用入门)),?scala
,?Groovy
,?JRuby
,?Jython
,?kotlin
等.
?