Java Tools

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            83 隨筆 :: 0 文章 :: 16 評論 :: 0 Trackbacks
          By Benny.luo@Sun.com, 6/19/07  
          SUN中國軟件技術中心 羅浩/Benny Luo
           簡介:
          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版本里面才有。< /li>
          • 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 <$Revision: 1.121.2.12 $> apache-2.0
          Copyright (c) 1996 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).....done
          Server Software: Resin/2.1.17
          Server Hostname: free.xxx.com
          Server Port: 8080
          Document Path: /forum/bbsMessageList.act?bbsThreadId=1580107
          Document Length: 27012 bytes
          Concurrency Level: 10
          Time taken for tests: 92.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.09 [#/sec] (mean)
          Time per request: 9214.888 [ms] (mean)
          Time per request: 921.489 [ms] (mean, across all concurrent requests)
          Transfer rate: 28.84 [Kbytes/sec] received
          Connection Times (ms)
          min mean[+/-sd] median max
          Connect: 0 0 0.0 0 0
          Processing: 9089 9187 139.4 9140 9789
          Waiting: 3067 3163 138.3 3117 3766
          Total: 9089 9187 139.4 9140 9789
          Percentage of the requests served within a certain time (ms)
          50% 9140
          66% 9178
          75% 9189
          80% 9201
          90% 9281
          95% 9560
          98% 9739
          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)
          - 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=195 (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=90 (Interpreted frame)
          - net._xxx.forum.model.user.UserInfo.getLogoPath() @bci=109, 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=94 (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=94 (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=95, 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=359 (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=39 (

          ..............

           和應用的開發人員交流后,發現這些有問題的程序,都是和論壇系統中Socket調用有關,當用戶打開一個頁面是,頁面中的用戶信息需要同過Socket的方式調用相冊那邊的數據,這個操作存在bug,經過用戶的重新同步更新程序,問題解決。
           
          解決后的實測的數據如下, 效果非常理想:
          This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
          Copyright (c) 1996 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.59
          Server Hostname: free.xxx.com
          Server Port: 80
          Document Path: /forum/bbsMessageList.act?bbsThreadId=1581280
          Document Length: 27508 bytes
          Concurrency Level: 30
          Time taken for tests: 252.583749 seconds
          Complete requests: 50000
          Failed requests: 0
          Write errors: 0
          Total transferred: 1384158363 bytes
          HTML transferred: 1375408188 bytes
          Requests per second: 197.95 [#/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] received
          Connection Times (ms)
          min mean[+/-sd] median max
          Connect: 0 0 0.4 0 11
          Processing: 45 150 154.1 117 4349
          Waiting: 41 145 153.7 112 4346
          Total: 45 150 154.1 117 4349
          Percentage of the requests served within a certain time (ms)
          50% 117
          66% 142
          75% 163
          80% 180
          90% 241
          95% 321
          98% 478
          99% 764
          100% 4349 (longest re
          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選項:
               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同步機制上,我們嘗試了改大數據連接池的大小,發現結果是一樣的。
          jdk5_1
          C.這個結論在jstack的結果中同樣得到了驗證,使用jstack連接到tomcat服務器java進程,并觀察結果。
          jdk5_2

          D. 最后我們決定用tomcat服務器的連接池配置來代替Primrose數據庫連接池,更改以后,發現結果比較理想。

          E. 后來,我們把Oracle數據庫建立在另外的一臺服務器X4200上,而Tomcat應用服務器依然放在T2000上,使用千兆網絡交換機,同樣地,使用Tomcat服務器自己的連接池配置表現較為理想。
          以上兩個是我對JDK5.0工具的一些實際操作的例子,在這里和大家分享一下,希望對大家有所幫助。而Sun Microsystem公司也在不斷地完善JDK,在新的JDK版本里面加入越來越多的實用的方便開發者開發和調試的新特性,比如在最新的JDK6.0里面就內嵌了Dtrace里面許多關于Java程序中內存,方法,線程等等新的探針,通過這些探針和Dtrace,我們可以更加方便地調試Java程序。
          文檔資料:
          posted on 2007-07-10 00:04 和田雨 閱讀(461) 評論(0)  編輯  收藏 所屬分類: J2SE
          主站蜘蛛池模板: 始兴县| 兴业县| 黎川县| 通化县| 自治县| 衡南县| 台湾省| 鱼台县| 油尖旺区| 舟山市| 马尔康县| 理塘县| 乌兰浩特市| 辉县市| 丘北县| 古丈县| 广东省| 崇左市| 英德市| 连江县| 陵川县| 木里| 于田县| 施甸县| 老河口市| 松阳县| 哈巴河县| 平远县| 顺平县| 股票| 南部县| 高碑店市| 鄢陵县| 安多县| 桦甸市| 诏安县| 炎陵县| 百色市| 乌恰县| 和平区| 河间市|