简介:
JDK5.0包括的调试工具:
jstack -- 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到 当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。目前只有在Solaris和Linux的JDK版本里面才有。
jconsole ? jconsole是基于Java Management Extensions (JMX)的实时图形化监测工具,这个工具利用了内建到JVM里面的JMX指令来提供实时的性能和资源的监控,包括了Java程序的内存使用,Heap size, 线程的状态,类的分配状态和空间使用等等。
jinfo ? jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息,目前只有在Solaris和Linux的JDK版本里面才有。
jmap ? jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等等,目前只有在Solaris和Linux的JDK版本里面才有。
jdb ? jdb 用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试,它的功能和Sun studio里面所带的dbx非常相似,但 jdb是专门用来针对Java应用程序的。
jstat ? jstat利用了JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控等等。
jps ? jps是用来查看JVM里面所有进程的具体状态, 包括进程ID,进程启动的路径等等。
另外,还有些其他附带的工具在这里没有列出,比如Heap Analysis Tool, kill -3 方法等等,这些在JDK5.0之前就有,同样也是非常有用的性能调优工具,大家可以参照相应的文档资料来学习,在文章后面也会推荐一些相应的文档给大家作为参考。
好,说了这么多,让我们来看看JDK5.0自带的这些工具在现实工作能给我们带来什么帮助,下面是我和ISV一起共同工作的实际例子,在这里把它们简单阐述出来,希望对大家有所帮助。
jconsole和jstack使用实例:
在做过的项目中,曾经有几个是使用jstack和jconsole来解决问题的。在下面的例子中,由于部分代码涉及到公司名字,我使用了xxx来代替。
整个应用的架构如下:Apache 2.0.5Array + Resin EE 2.1.17 + Jdk 1.5.0.07 + Oracle Array
运行的操作系统:Solaris 10 Update 3 (11/06), EIS patches包.
测试工具:Apache benchmark tool.
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1ArrayArray6 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking free.xxx.com (be patient).....doneServer Software: Resin/2.1.17
Server Hostname: free.xxx.com
Server Port: 8080Document Path: /forum/bbsMessageList.act?bbsThreadId=1580107
Document Length: 27012 bytesConcurrency Level: 10
Time taken for tests: Array2.148883 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 2722500 bytes
HTML transferred: 2701200 bytes
Requests per second: 1.0Array [#/sec] (mean)
Time per request: Array214.888 [ms] (mean)
Time per request: Array21.48Array [ms] (mean, across all concurrent requests)
Transfer rate: 28.84 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: Array08Array Array187 13Array.4 Array140 Array78Array
Waiting: 3067 3163 138.3 3117 3766
Total: Array08Array Array187 13Array.4 Array140 Array78ArrayPercentage of the requests served within a certain time (ms)
50% Array140
66% Array178
75% Array18Array
80% Array201
Array0% Array281
Array5% Array560
Array8% Array73Array
ArrayArray% Array78Array100% Array78Array (longest request)
Thread t@38: (state = BLOCKED)- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- com._xxx.vportal.common.rpc.session.RemoteServiceGroupFactory.getMaxBalanceFactoryEntry() @bci=165,
line=180 (Interpreted frame)
- com._xxx.vportal.common.rpc.session.RemoteServiceGroupFactory.getService() @bci=80, line=1Array5 (Interpreted
frame)
- com._xxx.vportal.common.rpc.session.RemoteServiceFactory.getSynSender() @bci=1, line=331 (Interpreted
frame)
- com._xxx.vportal.common.rpc.session.RemoteServiceSupport.synRequestHardTask(java.lang.String,
java.lang.Object) @bci=6, line=35 (Interpreted frame)
- com._xxx.vportal.amus.user.client.UserClientRpcImpl.getIconSigner(int, int) @bci=36, line=Array0 (Interpreted frame)
- net._xxx.forum.model.user.UserInfo.getLogoPath() @bci=10Array, line=546 (Interpreted frame)
- sun.reflect.GeneratedMethodAccessor13.invoke(java.lang.Object, java.lang.Object[]) @bci=36 (Interpreted frame)
- sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) @bci=6, line=25
(Compiled frame)
- org.apache.velocity.runtime.parser.node.ASTReference.execute(java.lang.Object,
org.apache.velocity.context.InternalContextAdapter) @bci=40, line=207 (Compiled frame)- org.apache.velocity.runtime.parser.node.ASTBlock.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=18, line=Array4 (Compiled frame)- org.apache.velocity.runtime.parser.node.SimpleNode.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=18, line=271 (Interpreted frame)-
org.apache.velocity.runtime.parser.node.ASTIfStatement.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=63, line=128 (Interpreted frame)- org.apache.velocity.runtime.parser.node.ASTBlock.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=18, line=Array4 (Compiled frame)- org.apache.velocity.runtime.directive.Foreach.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer, org.apache.velocity.runtime.parser.node.Node) @bci=Array5, line=344 (Interpreted frame)- org.apache.velocity.runtime.parser.node.ASTDirective.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=14, line=153 (Interpreted frame)- org.apache.velocity.runtime.parser.node.SimpleNode.render(org.apache.velocity.context.InternalContextAdapter,
java.io.Writer) @bci=18, line=271 (Interpreted frame)- org.apache.velocity.app.Velocity.evaluate(org.apache.velocity.context.Context, java.io.Writer, java.lang.String,
java.io.Reader) @bci=102, line=35Array (Interpreted frame)- org.apache.velocity.app.Velocity.evaluate(org.apache.velocity.context.Context, java.io.Writer,
java.lang.String, java.lang.String) @bci=18, line=253 (Interpreted frame)- net._xxx.forum.util.velocity.VelocityUtil.getVelocityEvaluate(java.util.Map, java.io.Writer,
java.lang.String) @bci=14, line=35 (Interpreted frame)
- net._xxx.forum.action.forum.BbsMessageListAction.go() @bci=1284, line=268 (Interpreted
frame)
?
net._xxx.forum.action.AbstractAction.execute() @bci=1, line=3Array (
?
..............
和应用的开发人员交流后,发现这些有问题的程序,都是和论坛系统中Socket调用有关,当用户打开一个页面是,页面中的用户信息需要同过Socket的方式调用相册那边的数据,这个操作存在bug,经过用户的重新同步更新程序,问题解决。
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1ArrayArray6 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/Benchmarking free.xxx.com (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Finished 50000 requests
Server Software: Apache/2.0.5Array
Server Hostname: free.xxx.com
Server Port: 80Document Path: /forum/bbsMessageList.act?bbsThreadId=1581280
Document Length: 27508 bytes
Concurrency Level: 30
Time taken for tests: 252.58374Array seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Total transferred: 1384158363 bytes
HTML transferred: 1375408188 bytes
Requests per second: 1Array7.Array5 [#/sec] (mean)
Time per request: 151.550 [ms] (mean)
Time per request: 5.052 [ms] (mean, across all concurrent requests)
Transfer rate: 5351.56 [Kbytes/sec] receivedConnection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.4 0 11
Processing: 45 150 154.1 117 434Array
Waiting: 41 145 153.7 112 4346
Total: 45 150 154.1 117 434Array
Percentage of the requests served within a certain time (ms)
50% 117
66% 142
75% 163
80% 180
Array0% 241
Array5% 321
Array8% 478
ArrayArray% 764
100% 434Array (longest re
整个应用的架构如下:Tomcat + Jdk 1.5 + Oracle 10g
运行的操作系统:Solaris 10 Update 3 (11/06), EIS patches包.
测试工具:LoadRunner 8.1
在实验的初段,Tomcat, Oracle 10g服务器都是架设在T2000上,我们在对T2000服务器的OS,网络,应用服务器做了必要的调整后,发现其表现还是不尽如人意。& #160;
A. 首先我们需要在Tomcat的启动脚本catalina.sh里面加入JVM选项:
Dcom.sun.management.jmxremote把tomcat服务器java进程置于JDK5.0的性能监控范围之内。B. 然后我们用jconsole连接到tomcat服务器的java进程,发现基本上Heap size, 垃圾回收都比较正常,但发现tomcat服务器的大部分线程有问题,都处于被Block的状态。
观察每条线程的stack trace, 发现它们基本上都被堵塞在uk.org.primrose.pool.core.Pool.put和 uk.org.primrose.pool.core.Pool.get()的SyncHack同步机制上,我们尝试了改大数据连接池的大小,发现结果是 一样的。
C.这个结论在jstack的结果中同样得到了验证,使用jstack连接到tomcat服务器java进程,并观察结果。
D. 最后我们决定用tomcat服务器的连接池配置来代替Primrose数据库连接池,更改以后,发现结果比较理想。
E. 后来,我们把Oracle数据库建立在另外的一台服务器X4200上,而Tomcat应用服务器依然放在T2000上,使用千兆网络交换机,同样地,使用Tomcat服务器自己的连接池配置表现较为理想。