JIP是一个代码剖析工具非常类似于JDK附带的hprof工具。它的特点包括:1.交互性,允许你在JVM运行过程中随时启动或结束剖析器而hprof是在程序启动时就开启JVM退出时结束。2.没有本地代码,大部分剖析器都有一些本地组件(native component)因为这些剖析器使用了需要利用本地组件的JVMPI (Java Virtual Machine Profiling Interface),而JIP是纯Java的,它利用了Java5?的一些特性。JIP对需要剖析的每一个类的每一个方法添加aspect拦截,这些aspect能够捕获执行数据。3.非常低的开销,在很多情况下hprof将会造成一个程序运行变慢20倍,而JIP是轻量级的几乎没有任何开销。4.JIP能够通过package/class名设置过滤器
下面是关于JIP的翻译文档,原英文在:http://jiprof.sourceforge.net/
翻译文档附件: http://download.csdn.net/detail/qyongkang/4488764
JIP 文档
JIP介绍
为什么要性能分析
为什么选择JIP
第1章 – 基本的性能分析
Command line
Non-interactive
Interactive
Tomcat
Eclipse
Timeline profiler
第2章 – JIP Viewer
第3章 – 进阶篇
编写自己的 Class Loader Filter
编写自己的 profiler
附件 A profile properties
附近 B DW article
JIP介绍
为什么要做性能分析?
性能分析是一种对程序的性能进行测试和分析的技术。它的意义就在于,当你发现你的程序很慢时,可以帮助你找到大部分时间花在了程序的哪一部分,通过这些分析,可以使你的代码朝着更加高效的方向发展。然而,如果一个应用程序是有性能问题,大多数开发人员可能选择直接通过代码查找,或直接认为是某一段代码的问题导致的。这样做肯定是有问题的,至少效率会很低下。
这种代码的局部优化,一般是通过对代码一行行的检查,去找到那些地方存在低效率的问题。在java语言中,有许多关于如何避免性能问题的说法:如 避免I/O操作,避免String或者说字符串类型操作,避免不必要的对象分配等等。从算法分析上来说,我们知道如何去量化使用的算法的效率,但是这些局部的一些优化可能并没有从根本上使出现问题的应用运行的更快更有效率。大多数在实际项目中的有经验的开发人员可能已经碰到了这样的问题,有些人可能已经花费了数天或者数周的时间去优化这些疑似有性能问题的代码,但是最后会发觉只有很少的一点效果或者提升。
在复杂的应用程序中,你需要将代码的性能看为一个整体,而不是仅仅的认为一小部分代码是性能的罪魁祸首。你可以优化你想优化的一些代码,但是如果这个代码时间占用了总时间的2%,那这个优化是不可能大大提高性能的。也有一些人认为在这里2%的提高,在别的地方的5%的提高,总的统计出来将会是一个可观的提升,但是我认为这样的做法是很难找到性能的瓶颈的,对于大的性能问题是很难有大的改进的。
另外一些经常采用的去优化性能的方式我把它称作为猜测或者依靠直觉的方式,开发者们可能会去“感觉”某一部分代码是慢的,这样的方式我认为总会是错误的。因为现在的的java应用程序都是很复杂的,所以就算是那些经常分析代码问题的人这样搞大部分时间也会是错误的,靠猜测去分析性能问题是不可能的。还有我们引用的很多三方类库也是增加复杂性的一方面,我们开发者们可能都不知道一个类库方法的调用花费的时间是多么昂贵的,因为通常情况下,他们并不知道这些类库的实现细节。
So.局部优化和靠直觉是不能帮助我们去优化java应用程序的,我们需要一种方法,这个方法将客观地衡量每一个代码级应用程序的性能,并且准确反映出来为了提高性能我们的code有哪些地方时需要fix的。
如何去分析
在java中有两种方法来衡量程序的性能。
第一种就是最常见的System.currentTimeMillis(),另外一种是使用像HPROF这样的自动化代码分析器 (hprof是随jdk发布的)。
使用System.currentTimeMillis()可能是最常用的衡量一段代码性能的技术了。最基本的做法就是在要检测的代码段前面加开始时间,在最后加结束时间,这两个时间之差就是这段代码花费的时间。这个方法是最简单和准确的,但是它有两大不足:其一:它是个手工过程,要求开发人员确定要测量哪个代码;插入工具代码;重新编译、重新部署、运行并分析结果;然后在结束时取消工具代码;而在下次出现问题时再次重复以上所有步骤。其二:它对于应用程序各部分的执行情况没有提供全面的观察。
另外一种性能测试的方式是使用像hprof这样的检测器。监测器避免了与即时测量相关联的问题,不需要编写额外的代码就可以使用。使用Hprof时,也不需要重新编译代码或者用特殊的方式来运行。它们还为程序性能提供了更全面的观察,因为它们收集每个方法调用的计时信息,而不仅仅是某个具体代码段的计时信息。不幸的是,监测工具也有不足。
现有检测方法的局限性
那么hprof是不是已经具备了我们需要的检测器的所有功能呢?显然不是的。Hprof是一个很好的工具,但是它确实还是有一些限制:
使用hprof时最悲催的事情在于它很慢。有多慢?就是用 hprof 运行程序,会把程序平均减慢 20 倍。这意味着正常情况下只需要一小时的一个 EFL(提取、转换、装入)操作,可能要花一整天才能监测!不仅等结果是不方便的,而且应用程序时间范围的改变,实际上也会扭曲结果。以做许多 I/O 操作的程序为例。因为 I/O 由操作系统执行,监测不会减慢它,所以 I/O 操作看起来运行得要比实际的速度快 20 倍!所以,不能总是依靠 hprof 提供对应用程序性能的正确描述。
hprof 的另一个问题与 Java 程序装入和运行的方式有关。与 C 或 C++ 这样的静态链接语言不同,Java 程序是在运行时而不是在编译时链接的。直到第一次引用的时候,JVM 才装入类,而代码直到执行了许多次之后,才从字节码编译成机器码。如果想测量一个方法的性能,但是它的类还没有装入,那么测量就会包含类的装入时间和编译时间再加上运行时间。因为这些事只在应用程序生命开始的时候发生一次,所以如果要测量长期的应用程序性能,通常不想把这些事包含在内。
还有另外一个问题是java classes文件是如何编译出来的。当你写好一个Java程序后,源语言的语句将由Java编译器编译成字节码。在运行时,JVM会将字节码编译为本地代码,以便应用程序将会运行得更快,这就是即时编译(JIT:just in time).
早期的JITS编译器是在类加载的时候将字节码编译为本地代码的,这种静态的编译非常类似于c和c++程序的编译方式。现在的即时编译器-JITS却不同,在生成本地代码之前,它使用一种动态编译器去监测代码实际是如何运行的。这种监测技术可以使JIT做一些优化,这种动态编译出来的代码比原来的静态代码编译性能更好。但是这种方式代码已经被JIT优化并且编译为本地代码,如果你想去衡量它的性能是比较难的。例如:在web application中,代码第一次执行时是比较慢的,因为他执行的是解释的字节码,而非优化过的本地代码。此外,类加载器加载的类可能会使事情变慢,甚至更慢。这些代码可能需要执行许多次之后,JIT才会将有的类优化编译为本地代码。在这些生命周期比较长的应用中,在classloader以及JIT干完他们的事之前你可能不像去测量这些代码的性能,但是不幸的是,像hprof这样的分析器是不允许你这样做的,或者说不那么容易坐到。
当代码在应用服务器或 servlet 引擎中运行的时候,事情会变得更加复杂。hprof 这样的监测器会监测整个应用程序、servlet 容器和所有的东西,他是监控在虚拟机层次的,它随着虚拟机启动就开始,随着虚拟机停止而结束。而问题是,通常我们是不想监测 servlet 引擎的,只想监测应用程序。
我们所需要的一个profiler应该是需要很少的开销,能随时停止随时启动的,一个轻量级的交互式分析器。
其他的问题
像选择其他工具一样,选择监测器也有机会成本。hprof 易于使用,但有局限性,例如不能从监测中过滤掉类或包。商业工具提供了更多特性,但是昂贵而且有严格的许可条款。
如果你应用的代码量非常庞大的话,那你麻烦就大了。比如hprof会分析每一个调用,而无法排除某些包或者,这就意味着会很多的无用的信息,但是这些都需要去整理。还有些调用可能是第三方类的调用,这些你也是无法直接修改的。可能有时你会蛋疼的想去看一下三方类库是如何工作的,但是大多数时候,你应该只想看和自己相关的代码。
可以想象一下,如果既能监控你想要的package/class,又能过滤掉你不关心的package/class(当然不能过滤掉它花费的时间),那会有多酷!
大多数像hprof这样的分析器是需要本地组件的,这主要是因为Sun性能分析接口-JVMPI(Java虚拟机性能分析接口),需要使用JNI(即,本地组件)。这意味着,在某种程度上,分析器是有很大的平台依赖性的。最好有个100%的Java写成的代码分析器。
还有一些麻烦,很多分析器是需要商业许可证的,像我们工作的企业中有多少是愿意购买付费软件的,除非很必要,而且很多情况下,工具能不能使用,还需要一整套的评估。开源软件的一大优势就是他可以随意的下载和使用,也不会有太多商业许可的麻烦。
JIP – The Java Interactive Profiler java交互式分析器
基于上面的种种原因,我开发一个新的工具,叫做JIP- the Java Interactive Profiler.你可以在SourceForge上下载使用:http://sourceforge.net/projects/jiprof. JIP是一个开源的,100% java开发的一个代码剖析工具。它利用了Java5?的一些特性
–javaagent VM选项。这个选项允许开发者在class加载时挂载到classloader上并且允许修改字节码。最基本的,JIP为每一个方法增加一个剖析面,它可以允许积累存储信息,编译downlaod下来分析。
它的特点包括, JIP 是:
? 交互式的:允许你在JVM运行过程中随时启动或结束剖析器而hprof是在程序启动时就开启JVM退出时结束。这允许开发者可以在运行时进行多次的测量,而不是像其他分析器所给的一次测量。
? 100% Java:JIP是纯Java的,它利用了Java5?的一些特性。大部分剖析器都有一些本地组件(native component),因为这些剖析器使用了需要利用本地组件的JVMPI (Java Virtual Machine Profiling Interface)。JIP对需要剖析的每一个类的每一个方法添加aspect拦截,这些 aspect能够捕获执行数据。
? 开源: JIP是遵循BSD开源协议的,你可以免费的下载和使用,也可以修改源码并发布。
? 轻量级: 在很多情况下hprof将会造成一个程序运行变慢20倍,而JIP是轻量级的几乎没有任何开销。另外一个好处是它允许你在目标程序运行时交互式的关闭或者打开剖析工具。当关闭JIP时,几乎是没有任何开销的。
? JIP能够通过package/class名设置过滤器:JIP允许你过滤掉你不关心的packahe/class,从而避免了一大堆无用的数据。
? 性能统计:JIP不仅是一个轻量级的剖析器,它也跟踪与收集的性能相关开销的数据。
? 可定制: JIP 允许开发者编写自己的剖析器,然后像一个插件一样加入JIP引擎
? 容易集成:JIP的输出选项之一可以是一个XML文件,文件中包含了统计数据。 XML文件可以很容易的编写工具去解析,然后将数据导入到其他系统。
使用JIP分析代码
首先你需要到Source Forge上去获取最新版本的JIP(http://sourceforge.net/projects/jiprof),我
The first thing that you will need to do is grab the latest release of JIP from Source Forge (http://sourceforge.net/projects/jiprof). 我将使用的版本是0.9.2。下载后解压,可以看到里面两个主要的目录:
/client
/profile
Profile这个目录包含了所有jar包性能分析的示例属性文件,属性文件中定义了分析器初始化默认的一些行为。Client目录包含了可以远程与分析器交互的文件。
要启用分析器,你可以在jvm启动的时候使用 –javaagent 选项,它的语法如下:
java –javaagent:%PROFILE-DIR%\profile.jar …
%PROFILE-DIR% 是profile 目录的全路径。
注意: 不要将这个目录放进Extensions loader 路径下,也不要将jar文件放到应用程序的classpath下。
这可能看起来有点奇怪,但是java agent会加载这个指定的jar文件,在%PROFILE-DIR%中的其他jar包将会被application classloader加载。 分析器配置的默认行为是默认打开的,远程访问是被关掉的(远程访问接口可以允许用户在运行时开启和关闭分析器)
在 Web Applications的应用
为了分析一个运行在Tomcate 5.5 上web 应用程序,你需要利用 JAVA_OPTS这个环境变量设置javaagent选项。在windows环境下,按如下设置:
SET JAVA_OPTS=–javaagent:%PROFILE-DIR%\profile.jar
当对一个web应用程序进行分析时,你可能想更改这个分析器的默认行为,特别是你可能想在开始时关闭分析器,而把远程接口打开,那么在/profile目录下有一个示例属性文件可以帮助你了解这些配置项如何设置。
这个文件名是:
webapp.profile.properties. 在文件中你可以看到有以下几个配置项:
profiler=off ---启动时分析器是关着的
remote=on ---远程接口开着
port=15599 --远程访问端口
你可以使用–Dprofile.properties 这个JVM参数来告诉JIP来使用这个配置文件:
SET JAVA_OPTS=–javaagent:%PROFILE-DIR%\profile.jar
–Dprofile.properties=%PROFILE-DIR%\webapp.profile.properties
使用JIP的默认配置时是非常简单的,在你的应用程序启动时JIP就可以开始分析,在VM终止时结束。交互式的使用JIP就像一个web应用程序一样,没有任何困难。一个例子:假如你有一个应用程序,其中有一个页面特别的慢,这个时候你想知道为什么这么慢?该如何做呢?你可以像上面描述的那样设置JAVA_OPS然后启动Tomcat。 为了得到性能分析的准确值,你可以先多访问几次页面,这可以避免这样页面正使用正在加载的类 ,也可以避免一些未完成的编译导致的不准确,比如jsp页面这种。我个人的话原则上在运行分析器之前会至少先访问这个页面6次,这样做的目的好像是给JIT足够的时间去编译完所有用到程序,但是请不要随便按我的建议来做哦, 我说6次,只不过在我的环境上看起来6是很神奇的数字而已。对于你来说情况可能并不相同,你可以从第一次页面访问开始分析,直到性能指数看起来比较平稳为止。在/client目录下有一些batch脚本可以用来与分析器进行交互,这些脚本都非常的简单,而且很容易一直到Unix系统下。如果你不想使用默认的一些配置,你首先要做的就是设置输出文件名,按如下方法:
File.bat localhost 15599 c:\tmp\test-profile.txt
(可以修改hostname,端口,以及合适的文件名)。这个配置修改并不会启动分析器,所以它可以在任何时间来做。 想要知道上面的设置是否成功,你可以观察Tomcat的输出日志,如果你看到有一行消息输出,这说明文件名已经设置成功了。然后当你觉得可以启动分析器的时候,用以下命令来启动:
Start.bat localhost 15599
这个命令并不会真正的启动分析器,这个命令实际上是告诉分析器去分析下一次运行的代码,所以不用着急。在你运行完你的测试用例后,你就可以停掉分析器然后dump下输出结果,用以下命令:
Finish.bat localhost 15599
如果你运行的是一个没有其他人在用的私有的Tomcat实例,那么也不用火急火燎的跑回控制台去执行上面的命令下载输出结果,take it easy!输出结果不会丢的,因为如果没有代码在执行的话,分析器是没有代码可分析的,结果也不会再变化。
上面的这些命令,你可以按需多次的执行。就我个人而言,我一般是在启动Tomcat时就带java agent的参数,这样的话如果我临时想去分析程序运行情况可以随时去分析,而不必重新启动Tomcat! 当启动Tomcat时设置java agent参数,同时保持分析器关闭着,你能看到和不设置javaagent参数的差别仅仅在于当tomcat启动时会稍微慢一些(这是因为有许多classes会被重写),但在Tomcat启动之后,就基本上看不出会比不带分析器慢了。
利用JIP分析第三方产品(类库)
虽然第三方产品你可能并不需要去分析,但是JIP确实可以分析它,说不定哪天就可以派上用场了。关于分析第三方类库的例子,随JIP发布的源码中有一个例子。这是个分析ANT编译JIP的例子,你可以使用example.bat这个脚本运行下观察下运行的情况。
分析: 通过JIP的分析结果来提升我们的code
JIP 输出内容解析
{Need to talk about interactions}
JIP输出结果的调用关系图(见附件A),从左到右的列依次为:
? 调用次数:给定方法被调用的次数
? 总时间:被调用方法的总耗时,以毫秒为单位
? 净耗时:这是调用方法的实际时间,排除调用其他方法所花费的时间的时间。这个净耗时是比所有子方法总计的耗时要少的。原因是有些被调用的方法是没有被罗列出来的,所以净耗时只是一部分时间,比如被bootstrap和extensions classloaders 加载的classes是不会被列出来的。如果你选择过滤掉一些被(web)application classloaderclass和package,他们的调用时间仍然会反映在这个方法的净耗时里。
? 总的百分比:被调用方法的总耗时在给定线程的总耗时中占的百分比。
? 净百分比: 被调用方法的净时间在给定线程中总耗时占的百分比。
有些分析器可以配置调用层次的深度,这个深度可以用profile properties 文件中的thread-depth 属性来设置控制,它的值可以是任意正整数,-1代表对调用层次的深度没有控制(默认是-1)。“compact” 属性也可以用来限制调用层次的深度,只有耗时达到设定的最低总耗时时才会被记录下来。这个最低 耗时可以用过thread.compact.threshold.ms.来设置,默认情况下的值为10 milliseconds。
中间部分(见附件B)是一个根据经耗时排序后的扁平版本的调用层次图,它的格式和最下面hprof的输出结果的格式几乎是相同的。层次图中输出的方法个数可以通过属性max-method-count属性来控制,如果没有特别指定的话,默认值是-1,表示没有限制。
最下面一部分 (见附件C)和中间的部分很像,但是有一个很大的不同。在上面的部分中,你可能注意到如果一个给定的方法在code中不同的地方调用多次,那么在调用图中也会出现多次。中间部分和上面部分很像,只不过是一个扁平版本的调用图,方法调用多次,结果也会有多次。最下面这部分有点不同,他是方法调用的汇总列表,列表中包含了调用次数,净耗时,所占百分比等 ,它可以认为是上面两种的调用层次的汇总信息,所有调用的方法只会出现一次。
如何来优化
得到了这些有用的信息后,很容易去跟踪和优化了,为了避免去做一些不重要的事情,请遵循以下几个原则:
? 只去优化那些真正有价值的部分
最下面的部分汇总了上面两个部分的调用信息,它给出了一个按调用方法耗时多少倒序排列的一个列表,看看列表的第三列—耗时百分比,这个指标将是我们的另一个优化分析准则:
? 把主要精力放在那些耗时占比超过10%或者更多的方法上
如果一个方法耗时占整个的2%,你可以去优化他,直到将它优化到耗时为0,但是这对于整个应用的性能来说可能并没有什么帮助。如果你有些独立的方法需要去优化,可以遵循下面两个简单的原则:
? 如果发现调用频率很高或者并发数很高,那么可以设法去降低这个方法的调用频率和并发数
? 如果调用频率不高,那么去看下这个方法是不是可以做一些局部的优化
如果所有的方法调用的净耗时都少于或者等于%5,那么可以去优化下一些主要的算法,这时候也可以去看看OS级别的相关指标,比如磁盘和网络I/O。
分析器也有不能相信的时候
分析器确实是一个很有价值的工具,但是有时候他的一些信息也不一定是准确的。特别是一些方法执行的很快,而且方法耗时很低,低于可测性的门槛,这时就很难去分析到。找一些调用频率很高但是净耗时很低的方法,当我去分析时,为了得到一段代码的平均性能,我经常是运行3次。如果你是这样做的,并且发现一些特定的方法调用结果如你所期望的那样变化,并且这个方法有很高的调用量,那么这样的方法的可测性是值得怀疑的。建议你不要浪费时间去优化这样的方法。
JIPViewer
进阶篇
- Programatic profile manipulation
在标准的Java environment 有以下三个 classloader:
Bootstrap
|
Extensions
|
Application
有-javaagent 选项指定的特定的jar包是由application classloader 来加载的。对JIP而言,这些jar包的类的用途是在其他类加载时重新装备这些类,比如植入一些监控代码。这些类包括被extensions classloader 加载的和被application classloader加载的类,这可能会导致一些问题:
1.如果你不排除这些类,那么分析器本身可能也会被监测,可以想象的到,这样是不太友好的。
2. 分析器本身是 –javaaagent选项加载的一部分,因此它是由application classloader 来加载的。但是那些被Extensions classloader加载的且已经被重新装备的用于运行时分析的类可能会引发一些问题,因为被Extensions classloader加载的类是不能被application classloader 加载的类所访问的,这将会导致ClassNotFound exception 异常出现。
3. 显而易见,解决办法就是不去对extensions classloader 加载的类进行装备。在ClassLoader类 中有一个静态方法可以告诉我们应用程序的classloader是哪一个(getSystemClassLoader()),这是个不错的消息吧?也许是。因为对于独立的应用来说确实很给力,但是对于web应用程序来说,它依然不靠谱。对于一个servlet容器他的classloader层次会更深,而且也没有一个标准说这种层次关系应该长成什么样子(顺便说一下,在servlet容器中,调用getSystemClassLoader()方法会返回VM启动servlet引擎所使用的classloader)。因为Tomcat 5.5是开源的,所以我们知道是是哪个classloader为我们的web应用加载类。
常见问题
Q: 是不是必须将profile.jar 放在我应用的classpath中?
A: 不是的,事实上建议你不要将它放在你的classpath下。
Q:我运行了JIP,但是没有输出结果,这是为什么?
A: 有一些原因会导致这个情况发生,下面我列出一些需要检查的点:
? 首先确认你想分析的代码不在JIP配置文件的排除列表里(exclude list)
? 如果你排除了上面的可能仍然没有输出结果,那么可以将属性文件中的debug属性设置为on, 这会输出哪些class正在被装备,哪些没有。密切关注一下每个类正在被那个classloader装载。还请注意下独立的应用,那些被extension classloader(i.e,, -Djava.ext.dirs=…)加载的类是不会被增强的。
? 检查一下当前正在分析的工作目录的Unix权限,这个不是很常见。
? 尽量使用绝对路径而不是相对路径,有时候程序的当前工作目录并不是你想象的那样。
? 附件 A – Profile Properties
使用分析器的属性文件改变JIP的行为
Java Interactive Profiler (JIP)的默认行为是可以通过一个属性文件改变的。 这只是一个标准的java properties文件,你可以通过VM参数profile.properties指定属性文件的文件名。例如你想使用my-profile.properties文件作为profiler的属性文件,你启动JVM时应该像下面这样:
java -Dprofile.properties=my-profile.properties ....
目前 JIP 1.0 支持以下属性配置:
* profiler
* remote
* port
* ClassLoaderFilter.x
* thread-depth
* thread.compact.threshold.ms
* max-method-count
* method.compact.threshold.ms
* file
* exclude
* track.object.alloc
* output
* debug
* profiler-class
* output-method-signatures
* clock-resolution
profiler
Values: on, off
Defalut: on
描述: 这个属性控制VM启动时是否开始分析收集信息,通常情况下,你可能希望按照自己所需来开启或者关闭,比如当你在命令行下观察问题时开着,正常访问webapp的时候是关着的。
remote
Values: on, off
Default: off
描述:控制远程访问接口是否可用。Profiler的远程访问接口允许你在运行时开启或者关闭profiler。这可以使你在不用重启应用的情况下做多次监测。这个配置通常情况对于webapps应用下你希望是开着的,命令行应用模式下是关着的。
port
Values: 任何有效的TCP端口值
Default: 15599
描述:这个配置项控制远程访问接口监听的接口。
ClassLoaderFilter.x
Values: com.mentorgen.tools.profile.instrument.clfilter.ClassLoaderFilter的任何有效实现类
Default:如果你没有指定filter,默认使用 com.mentorgen.tools.profile.instrument.clfilter.StandardClassLoaderFilter
描述:JIP必须知道哪一个加载class的classloader是要被监测分析的。在命令行应用下我们是知道的,但是在webapps和其他类型的应用是使用不同的classloader 的。解决办法就是定义一个接口: ClassLoaderFilter 使用一个责任链模式来决定分析时挂载到哪个classloader。这种方式下你可以定义这个接口的多个实现,每个实现有不同的使用环境。你可以在ClassLoaderFilter后面附件一个数字来指定搜索的顺序。例如,profiler的标配如下:
ClassLoaderFilter.1=com.mentorgen.tools.profile.instrument.clfilter.WebAppClassLoaderFilter
ClassLoaderFilter.2=com.mentorgen.tools.profile.instrument.clfilter.StandardClassLoaderFilter
如果我们运行Tomcat环境的话,WebAppClassLoaderFilter会被调用,如果调用失败的话,StandardClassLoaderFilter会接着被调用。请注意,现在只支持Java5(tm)和Tomcat环境,如果有人想添加对其他环境的支持,我也非常支持。
thread-depth
Values: 任何正整数,-1 或者 compact
Default: -1
Description: 调用堆栈可能会非常深,然而有时你可能只想看到某个层次就够了,这个参数就是可以控制你能看到的调用堆栈深度。默认值是-1,表示没有限制。另外可以用的值是 compact,这个配置可以根据调用耗时的总时间来限制调用堆栈,默认至少是10ms(默认配置可以修改)。相对于强加一个thread-depth的限制来说,使用compact配置是一个不错的方式。
thread.compact.threshold.ms
Values: 任何正整数
Default: 10
Description: 根据调用的总耗时来限制调用堆栈输出结果,这个配置只有在thread-depth属性设置为compact的时候才会生效。
max-method-count
Values: 任何正整数,-1或者compact
Default: -1
Description: 这个属性控制profiler输出最耗时的方法。-1代表没有任何限制,配置一个大于-1的数字就可以限制输出的方法数。Compact值的意义在于只有当方法耗时超过了一个特定值时才会被记录下来,这个特定值默认是10ms,它是可以通过配置项method.compact.threshold.ms来修改的。
method.compact.threshold.ms
Values: 任何正整数
Default: 10
Description: 只有耗时超过了指定时间的方法才会被输出结果,这个配置只有当max-method-count 属性的值设置为compact时才会生效。
file
Values: 任何有效的文件或者目录名
Default: ./profile.txt
Description: profiler的输出结果文件名。如果你配置的是一个目录,那么JIP将会自动产生一些文件,然后放入这个目录下。自动产生的文件名格式如: yyyyMMdd-HHmmss.
exclude
Values: 一个被分隔开的package或者class的列表(class名字必须是全路径,比如com.alibaba.b2b.crm.app.HelloWorld)。
Default: 无默认值
Description: 这个配置的目的是从profile中排除一些不想被分析的package和class。如果你有些package和class就是不想被profile分析,那这个配置是很方便的。需要注意的是:只有那些被 “app” classloader加载的类才可以。
track.object.alloc
Values: on or off
Default: off
Description: 控制JIP是否跟踪对象的分配
output
Values: text, xml 或者 两者
Default: text
Description: 除了人类可读的格式外,这个选项允许你以原始的XML格式输出监测的信息。
debug
Values: on or off
Default: off
Description: 当debug选项被打开后,每当profiler监测到一个class被加载就会将text文本发送到标准输出(see com.mentorgen.tools.profile.instrument.Transformer)。如果这个类被instrumented,类名加classloader名加在一起会被发送到stdout。如果这个类没有被instrumented,不会被监测到,直接跳过。
此外,如果监测到异常,或者被检测方法还未完成而profiler突然中断,那么信息会被发送到standard error端。
profiler-class
Values: 任何class名称
Default: com.mentorgen.tools.profile.runtime.Profile
Description: allows the another profiling backend to be used.
output-method-signatures
Values: yes or no
Default: no
Description: 当被设置为yes时,会输出方法签名。默认情况下,为了节省空间方法签名信息被忽略了。如果你正处理的方法是被重新加载了,你能够看到方法签名信息。
clock-resolution
Values: ms or ns
Default: ns
Description: Sets the resolution of the TimeLineProfiler's clock to either milliseconds (ms) or nanoseconds (ns). Only valid when using the TimeLineProfiler.