HPROF: 一个Heap/CPU Profiling工具
http://blog.csdn.net/ae86_fc/article/details/5960719
J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profiling,叫做HPROF。HPROF实际上是JVM中的一个native的库,它会在JVM启动的时候通过命令行参数来动态加载,并成为 JVM进程的一部分。若要在java进程启动的时候使用HPROF,用户可以通过各种命令行参数类型来使用HPROF对java进程的heap或者 (和)cpu进行profiling的功能。HPROF产生的profiling数据可以是二进制的,也可以是文本格式的。这些日志可以用来跟踪和分析 java进程的性能问题和瓶颈,解决内存使用上不优的地方或者程序实现上的不优之处。二进制格式的日志还可以被JVM中的HAT工具来进行浏览和分析,用 以观察java进程的heap中各种类型和数据的情况。
在J2SE 5.0以后的版本中,HPROF已经被并入到一个叫做Java Virtual Machine Tool Interface(JVM TI)中。
HPROF的启用
HPROF可以用来展示和跟踪cpu的使用情况,内存分配的统计数据等。不仅如此,它还支持对
java进程完整的内存dump,所有线程的monitor stats数据。HPROF被启用的方式可以如下:
java
-agentlib:hprof[=options] ToBeProfiledClass
或者
java
-Xrunhprof[:options] ToBeProfiledClass
HPROF如何构建java进程,并发送进程的jvm
profiling信息,取决于HPROF在JVM启动时从命令行获取的参数指令。比如,以下指令将会获取java进程的heap
allocation的profile:
java -agentlib:hprof=heap=sites
ToBeProfiledClass
HPROF
可以被指定的参数非常的多,以下是完整的列表:
java -agentlib:hprof=help
HPROF: Heap
and CPU Profiling Agent (JVM TI Demonstration Code)
hprof usage: java
-agentlib:hprof=[help]|[<option>=<value>, ...]
Option Name and
Value Description Default
--------------------- ----------- -------
heap=dump|sites|all heap profiling all
cpu=samples|times|old CPU usage off
monitor=y|n
monitor contention n
format=a|b
text(txt) or binary output a
file=<file>
write data to file java.hprof[.txt]
net=<host>:<port> send data over a socket off
depth=<size>
stack trace depth 4
interval=<ms> sample interval in ms 10
cutoff=<value> output cutoff point 0.0001
lineno=y|n
line number in traces? y
thread=y|n
thread in traces? n
doe=y|n
dump on exit? y
msa=y|n
Solaris micro state accounting n
force=y|n
force output to <file> y
verbose=y|n
print messages about dumps y
Obsolete Options
----------------
gc_okay=y|n
Examples
--------
- Get sample cpu
information every 20 millisec, with a stack depth of 3:
java
-agentlib:hprof=cpu=samples,interval=20,depth=3 classname
- Get heap usage
information based on the allocation sites:
java
-agentlib:hprof=heap=sites classname
默认情况下,java进程profiling的信息(sites和dump)都会被
写入到一个叫做java.hprof.txt的文件中。大多数情况下,该文件中都会对每个trace,threads,objects包含一个ID,每一
个ID代表一个不同的观察对象。通常,traces会从300000开始。
默认,force=y,会将所有的信息全部输出到output文件中,所以如果含有
多个JVMs都采用的HRPOF
enable的方式运行,最好将force=n,这样能够将单独的JVM的profiling信息输出到不同的指定文件。
interval选项只在
cpu=samples的情况下生效,表示每隔多少毫秒对java进程的cpu使用情况进行一次采集。
msa选项仅仅在Solaris系统下才有效,
表示会使用Solaris下的Micro State Accounting功能
Examples
我们可以自己写一个java应用程序,但是例子
里将使用一个J2SE中已有的java应用程序,javac。
Heap Allocation Profiles(heap=sites)
以下是对一个java代码文件运行java编译
器javac的heap allocation profile日志的一部分:
Command used: javac
-J-agentlib:hprof=heap=sites Hello.java
从日志中可以看到程序在运行的每一个部分都消耗了多少内存的heap
profile数据。以上日志可以看出,整个程序的heap中有44.73%的被分配给了java.util.zip.ZipEntry对象。同时可以观
察到,live
data的数量跟所有allocated的总数是匹配atch的,这就说明GC可能在HPROF遍历整个heap搜集信息的很短的时间之前已经做过一次内
存回收了。通常情况下,live data的数量是会稍微少于所有allocated的总数的。
Heap Dump (heap=dump)
该选项用来对java进程的heap进行进行完
全的dump:
Command used: javac -J-agentlib:hprof=heap=dump Hello.java
这样会产生一个非常大的输出文件,但是可以用任
何编辑器进行打开和搜索。但是,更好的观察和分析办法是通过HAT来进行分析和观察。所有用heap=sites选项中获取的信息这里也都可以获取到。另
外还加上一些特别的细节数据。如对每个对象的内存分配以及其引用的其他所有的对象。
该选项会使用很多的内存,因为它会将所有对象的
内存分配情况全部记录下来,同时也可能会影响到应用程序本身的性能,因为数据的产生会影响对象分配和资源回收。
CPU Usage Sampling
Profiles (cpu=samples)
HPROF可以用来搜集java进程中各个threads的cpu使用情况:
HPROF会对java进程中所有的threads进行周期性的stack
traces采集。以上count一列就表示在采集中有多少次的stack
trace被HPROF发现,并且是active的(而不是指一个method被执行了多少次)。这些stack
traces包括cpu的使用,哪些是cpu消耗热点。
那么以上日志中可以看出什么信息呢?第一,统计数据的样本数据是很少的,只有126次的采样,如
果是比较大的程序编译,那么应该能够产生更有代表性的数据。第二,该数据跟以上对heap=sites的采集数据比较匹配,ZipFile耗费了比较多的
cpu时间和调用次数。在以上采集中,可以发现,跟ZipFile相关的的性能在javac中都会消耗的比较高,该ZipFile的stack
trace如下:
CPU Usage Times Profile (cpu=times)
HPROF可以通过对java应用程序的各个方
法中注入code的方式来搜集各个method的执行情况。对每个methods的执行情况进行跟踪,count以及时间消耗的搜集。这种技术叫做
Byte Code Injection。所以这种采集方式的运行比cpu=samples要慢很多,以下是采集数据日志:
这里的count代表着该方法被真正执行了多少次,并且方法thread消耗了多少精确的cpu
时间。