用JDK5.0自带工具解决实际工作中的问题
百度广告
JDK 5.0, 代号老虎,在以往的Java传统上加入了许多新的设计,给Java语言带来了一些较大的变化,比如泛型,元数据,可变个数参数,静态导入类,新线程架构,自动装箱/拆箱等等新的以往没有的新特性。同时,在调试程序和解决性能各种问题方面,JDK5.0同样加入了多个分析工具来让开发者更加方便地调试他们自己的程序,它们包括了命令行调试工具,图形界面调试工具等等.
JDK5.0包括的调试工具
我们在这里对JDK5.0的调试工具做大致的概念性的介绍,然后希望通过介绍我自己在实际工作中使用这些工具解决问题的实例来让大家对这些工具有更深入的了解。
JDK5.0里面加入了jstack, jconsole, jinfo, jmap, jdb, jstat, jps, 下面对这些工具做简单介绍
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来代替。
1. 其中的一个是Web2.0的客户,由于目前Sun Microsystem公司推出的Niagara服务器系列非常适合网络方面的多线程应用,并且已经在业界非常出名,所以他们决定使用T2000服务器来测试一下如果应用到他们自己的应用是否能够获得出众的性能。
整个应用的架构
Apache 2.0.59 + Resin EE 2.1.17 + Jdk 1.5.0.07 + Oracle 9
Solaris 10 Update 3 (11/06), EIS patches包.
Apache benchmark tool.
在客户的测试环境中,我们分别做了Apache, Resin, Solaris的相应调整,其中包括了Apache使用Prefork模式,并且调整了httpd.conf文件里面相应的ServerLimit, ListenBacklog,Maxclient等等值,Resin服务器调整Jvm heap size, 并行回收new generation和old generation, 最大线程数,oracle连接数等等参数,Solaris操作系统做了网络和系统的相应调整,最终把整套系统搬进了生产环境,一切顺利进行,但当进入其中的一个系统时却发现系统响应时间非常缓慢,用Apache Benchmark Tool加少量压力得到结果如下,由于是在生产环境下所以不敢使用大的压力
This is ApacheBench, Version 2.0.41-dev apache-2.0
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking free.xxx.com (be patient).....done
Server Software: Resin/2.1.17
Server Port: 8080
Document Path: /forum/bbsMessageList.act?bbsThreadId=1580107
Concurrency Level: 10
Complete requests: 100
Write errors: 0
Total transferred: 2722500 bytes
Requests per second: 1.09 [#/sec] (mean)
Time per request: 921.489 [ms] (mean, across all concurrent requests)
Connection Times (ms)
Connect: 0 0 0.0 0 0
Waiting: 3067 3163 138.3 3117 3766
Percentage of the requests served within a certain time (ms)
66% 9178
80% 9201
95% 9560
99% 9789
100% 9789 (longest request)
每一个请求的响应时间大概去到8-9秒时间,这个是客户所不能接受的。|||
这时我们决定采用JDK5.0自带的jstack来进行trouble-shoot,首先重新做加压测试,并行请求为10个,总共100个请求,这时对Resin服务器所起的Java进程间隔10秒用jstack做一次采集工作。为什么要间隔10秒?主要是想看看在这三十秒内Java进程是否都阻塞在同一个地方。结果
大部分的线程都阻塞在同一个java stack上面:
Thread t@38: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Interpreted frame)
- com._xxx.vportal.common.rpc.session.RemoteServiceGroupFactory.getMaxBalanceFactoryEntry() @bci=165,
- com._xxx.vportal.common.rpc.session.RemoteServiceGroupFactory.getService() @bci=80, line=195 (Interpreted
- com._xxx.vportal.common.rpc.session.RemoteServiceFactory.getSynSender() @bci=1, line=331 (Interpreted
- com._xxx.vportal.common.rpc.session.RemoteServiceSupport.synRequestHardTask(java.lang.String,
- com._xxx.vportal.amus.user.client.UserClientRpcImpl.getIconSigner(int, int) @bci=36, line=90 (Interpreted frame)
- sun.reflect.GeneratedMethodAccessor13.invoke(java.lang.Object, java.lang.Object) @bci=36 (Interpreted frame)
(Compiled frame)
org.apache.velocity.context.InternalContextAdapter) @bci=40, line=207 (Compiled frame)
- org.apache.velocity.runtime.parser.node.ASTBlock.render(org.apache.velocity.context.InternalContextAdapter,
- org.apache.velocity.runtime.parser.node.SimpleNode.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,
- org.apache.velocity.runtime.directive.Foreach.render(org.apache.velocity.context.InternalContextAdapter,
- org.apache.velocity.runtime.parser.node.ASTDirective.render(org.apache.velocity.context.InternalContextAdapter,
- org.apache.velocity.runtime.parser.node.SimpleNode.render(org.apache.velocity.context.InternalContextAdapter,
- org.apache.velocity.app.Velocity.evaluate(org.apache.velocity.context.Context, java.io.Writer, java.lang.String,
- org.apache.velocity.app.Velocity.evaluate(org.apache.velocity.context.Context, java.io.Writer,
- net._xxx.forum.util.velocity.VelocityUtil.getVelocityEvaluate(java.util.Map, java.io.Writer,
- net._xxx.forum.action.forum.BbsMessageListAction.go() @bci=1284, line=268 (Interpreted
–
–
和应用的开发人员交流后,发现这些有问题的程序,都是和系统中Socket调用有关,当用户打开一个页面是,页面中的用户信息需要同过Socket的方式调用相册那边的数据,这个操作存在bug,经过用户的重新同步更新程序,问题解决。
解决后的实测的数据如下, 效果非常理想
This is ApacheBench, Version 2.0.41-dev apache-2.0
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking free.xxx.com (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Finished 50000 requests
Server Hostname: free.xxx.com
Document Path: /forum/bbsMessageList.act?bbsThreadId=1581280
Concurrency Level: 30
Complete requests: 50000
Write errors: 0
HTML transferred: 1375408188 bytes
Time per request: 151.550 [ms] (mean)
Transfer rate: 5351.56 [Kbytes/sec] received
Connection Times (ms)
Connect: 0 0 0.4 0 11
Waiting: 41 145 153.7 112 4346
Percentage of the requests served within a certain time (ms)
66% 142
80% 180
95% 321
99% 764
2. 另外的一个是最近做的,我们有个教育行业方面的ISV上来实验室做T2000的Benchmark实验,我们花了一天的时间部署整个架构,包括安装Solaris操作系统,应用服务器,数据库。& amp; amp; lt; /div> 整个应用的架构
Tomcat + Jdk 1.5 + Oracle 10g
Solaris 10 Update 3 (11/06), EIS patches包.
LoadRunner 8.1|||
在实验的初段,Tomcat, Oracle 10g服务器都是架设在T2000上,我们在对T2000服务器的OS,网络,应用服务器做了必要的调整后,发现其表现还是不尽如人意。& #160;
我们使用Loadrunner做测试,用户上到了100个同时并发10个迭代时已经出现问题,有许多的请求都被阻塞住,不能正常地进行。
这时我们决定使用jconsole和jstack来看看系统出现了什么问题。
A. 首先我们需要在Tomcat的启动脚本catalina.sh里面加入JVM选项:
把tomcat服务器java进程置于JDK5.0的性能监控范围之内。
B. 然后我们用jconsole连接到tomcat服务器的java进程,发现基本上Heap size, 垃圾回收都比较正常,但发现tomcat服务器的大部分线程有问题,都处于被Block的状态。
C.这个结论在jstack的结果中同样得到了验证,使用jstack连接到tomcat服务器java进程,并观察结果。
D. 最后我们决定用tomcat服务器的连接池配置来代替Primrose数据库连接池,更改以后,发现结果比较理想。
编辑推荐:
温馨提示:因考试政策、内容不断变化与调整,长理培训网站提供的以上信息仅供参考,如有异议,请考生以权威部门公布的内容为准! (责任编辑:长理培训)
点击加载更多评论>>