塹壕からの眺め:スレッドダンプの研究

オリジナルリンク: http://www.cnblogs.com/kapok/archive/2005/10/15/255398.html

http://dev2dev.bea.com.cn/techdoc/200403149.html

任意のソフトウェアシステム、関係なく、慎重に起因するインタラクションデザイナーやボトルネックの要因に、コード化された方法を予見することはできません、ゆっくり実行するために秋のポイントまたは一顧が常にあります状況マシン。、その最終層の組成にBEA WebLogic Platformのと同様、このような複雑なシステムの場合、それは非常に重要であり、このような問題に対処する方法を理解し、異なるユーザによって変化します。

市場でWebLogic Javaソリューションとして、この複合体の健康状態を監視するための様々なプログラムがあります。DirigパフォーマンスモニタとウィリーTechのIntroscopeを、それはちょうど2つのこのようなプログラムです。しかし、それはその後、どうなる必要があなたがしている場合はインストールされていない、またはそれは十分に深いシステムに統計データを記録することに失敗した場合(例えば、情報をボトルネックスレッド)?スレッドダンプ:BEAは、専門家やサポートスタッフが、これらすべての似たような状況に既製の答えを与えている経験しました。各Java仮想マシンは、ある時点の状態で、すべてのスレッドのタイムリーな世代ディスプレイ機能スレッドダンプを持っています。5スレッドダンプを使用して30秒間隔で、あなたは世界の同期方法を待ってキャッチし、その無限のデッドロックに巻き込まれた、アクティブであるかのスレッドを見ることができます。いずれにせよ、それは常に問題を解決します。
事務の現在の状態
実際には、各Java仮想マシン--- Java仮想マシンのも、主流のバージョン---形式のスレッドダンププリントアウトの異なるいくつかのマイナーがあり、いくつかの簡単なデッドロックの分析、他の人がロックを表示しません。でも、市販ツールの分析を、スレッドダンプ、情報を取得すると、同じスレッドダンプで作業することはできませんJVMPIデバッグ・インタフェースの使用が採用されています。以下は提示三つの異なるJava仮想マシンで同じプログラムの状態を示し三つのセクションからの抜粋です:

日JVM 1.3.1スナップショットフル・ダンプ

完全なスレッドダンプ:

 
               "TDeadLock-1A" PRIO = 5 TID = 0x89c0d98 NID = 0xa90モニタエントリを待っ[0x8fcf000..0x8fcfdb8]
                       TDeadLock.method2で(ThreadDumpTester.java:147)
                       TDeadLock.method1で(ThreadDumpTester.java:138)
                       TDeadLock.runで(ThreadDumpTester.java:121)
                       java.lang.Thread.runで(Thread.java:479)
 
                       ......
 
                       Javaレベルのデッドロックが見つかりました:
               ----------------------------
               "TDeadLock-1B":
                 (0x2968468、java.lang.Objectのオブジェクト)モニター0x8022f4をロックするのを待って、
                 「TDeadLock-1A」でロックされています
               "TDeadLock-1A":
                 (0x2968470、java.lang.Objectのオブジェクト)モニター0x8022d4をロックするのを待って、
                 「TDeadLock-1B」によってロックされています
 
               上記のスレッドのJavaスタックINFORMATION:
               ------------------------------------------------
               "TDeadLock-1B" のJavaスタック:
               ==========
                       TDeadLock.method2で(ThreadDumpTester.java:147)
                       - ロックを待機している(java.lang.Object上位)
                       TDeadLock.method1で(ThreadDumpTester.java:138)
                       - (java.lang.Objectの)ロック
                       TDeadLock.runで(ThreadDumpTester.java:121)
                       java.lang.Thread.runで(Thread.java:479)
               "TDeadLock-1A" のJavaスタック:
               ==========
                       TDeadLock.method2で(ThreadDumpTester.java:147)
                       - ロックを待機している(java.lang.Object上位)
                       TDeadLock.method1で(ThreadDumpTester.java:138)
                       - (java.lang.Objectの)ロック
                       TDeadLock.runで(ThreadDumpTester.java:121)
                       java.lang.Thread.runで(Thread.java:479)
 
               ....
               2つのデッドロックが見つかりました。
 
        

Sun JVM 1.4.1 快照 (Full dump)

Java HotSpot(TM) Client VM (1.4.1_03-b02 混合模式)虚拟机下的完整的Thread dump:

 
               "TDeadLock-1a" prio=5 tid=0x00960A60 nid=0x8bc waiting for monitor entry [b0cf000..b0cfd88]
                       at TDeadLock.method2(ThreadDumpTester.java:147)
                       - waiting to lock  (a java.lang.Object)
                       at TDeadLock.method1(ThreadDumpTester.java:138)
                       - locked  (a java.lang.Object)
                       at TDeadLock.run(ThreadDumpTester.java:121)
                       at java.lang.Thread.run(Thread.java:536)
 
               .....
               Found one Java-level deadlock:
               =============================
               "TDeadLock-1b":
                 waiting to lock monitor 0x8fec7c (object 0x2a3f7e0, a java.lang.Object),
                 which is held by "TDeadLock-1a"
               "TDeadLock-1a":
                 waiting to lock monitor 0x8fec5c (object 0x2a3f7e8, a java.lang.Object),
                 which is held by "TDeadLock-1b"
 
               Java stack information for the threads listed above:
               ===================================================
               "TDeadLock-1b":
                       at TDeadLock.method2(ThreadDumpTester.java:147)
                       - waiting to lock  (a java.lang.Object)
                       at TDeadLock.method1(ThreadDumpTester.java:138)
                       - locked  (a java.lang.Object)
                       at TDeadLock.run(ThreadDumpTester.java:121)
                       at java.lang.Thread.run(Thread.java:536)
               "TDeadLock-1a":
                       at TDeadLock.method2(ThreadDumpTester.java:147)
                       - waiting to lock  (a java.lang.Object)
                       at TDeadLock.method1(ThreadDumpTester.java:138)
                       - locked  (a java.lang.Object)
                       at TDeadLock.run(ThreadDumpTester.java:121)
                       at java.lang.Thread.run(Thread.java:536)
 
               ....
               Found 2 deadlocks.
        

JRockit JVM 1.4.2 快照 (Full dump)

 
 
               ===== FULL THREAD DUMP ===============
               Tue Dec 23 16:43:14 2003
 
               "TDeadLock-1a"  id: 0x00000980  prio: 5  ACTIVE, NONDAEMON, GCABLE
               thread: 0x40EC5808  lastj: 0x4191FDB0  pt_thr: 0x00000228
                       at jrockit/vm/Threads.progressiveNap(Native Method)D10D60
                       at jrockit/vm/Locks.stage2Lock(Native Method)D10FD4
                       at jrockit/vm/Locks.monitorEnter(Native Method)D11070
                       at TDeadLock.method2(ThreadDumpTester.java:145)
                       at TDeadLock.method1(ThreadDumpTester.java:138)F7
                       at TDeadLock.run(ThreadDumpTester.java:121)A2
                       at java/lang/Thread.run(Unknown Source)D501
                       at java/lang/Thread.startThreadFromVM(Unknown Source)D1F173
                       --- End of stack trace
 
               ....
 
               =====================
               


有哪些共同点?
· dumps包含线程;线程的运行状态、标识和调用的堆栈。
· 调用的堆栈包含完整的类名,所执行的方法,如果可能的话还有源代码的行数。

有哪些不同点?
· 在Sun's JVM 1.4.1快照中包含若干锁定的信息行。
· 在Sun's JVM 1.3.1 可以用-XX:+JavaMonitorsInStackTrace标记启用锁定行,但并不是很多人都了解这一点。
· Sun的Java虚拟机有附加的不一致的开销部分。
· 在包名称和介于线程名与其堆栈跟踪之间的附加行有Jrockit的分隔符。
· thread-dump的时间(有用的)和线程堆栈的最后行有Jrockit的附加修饰。
正如你所见,尽管在所有的thread-dump类型中都存在大量有用的公共信息,但要分析来自多家供应商或者即使是同一家供应商但却是多种版本的Java虚拟机的thread-dump,还仍然有大量的工作要做。将它们与能够做出实际比较的代码结合起来,关联并插入结果,从而你将得到一个脆弱的、难以维护和扩展的应用程序。事实上,我的确有两个具有分歧的应用程序,用于为文本和HTML表示来分析thread-dump,并且它们在功能方面很难保持同步。

一个合适的提议
要想自己尝试这些例子,需要下载作者编写的带有析取器和xsl处理脚本的应用程序。这里最为完美的解决方案是,能够将这些thread-dump转换到某种中间形式的结构/语言,而它又具有灵活的架构,能够容忍丢失信息,并能被第三方工具以多种方式处理。当然,如果它能以某种方式涉及一种当前流行的技术,那就更好了。

我们有这样一种中间语言吗?事实上我们有,那就是XML。它在某种程度上是人类可读的,有许多编写工具,并且有建立在它之上的多种转换和报表技术,如XSLT、XQuery和XDB.

在这一场合下,析取器工具将只有一个作用:分析特定的Java虚拟机的格式,并将其转换成包含所有模式的XML文档。

以下是在Sun的 1.4.1 JVM中XML文档的例子:

Sun JVM 1.4.1 XML (良好的可打印片段) (完整的XML)

现在我们已经有了一个XML文档。而它可能比初始源文件更一致,我们实际上能对它做些什么呢?让我们想想。我们将使用一个实际的带有三个thread-dump的thread-dump序列。

( 初始的thread-dump --> 已析取的 XML)

· 将thread-dump信息转换成更易进行字符串查找的文本形式
(样式表--> 完整结果)

 
        Dump-1
               d1-Prototyper
                       method:: java.lang.Object:wait---Native Method:
                       lock:: waiting on-->org.logicalcobwebs.proxool.ConnectionPool(0x5baf0200)
                       method:: java.lang.Object:wait---Object.java:426
                       method:: org.logicalcobwebs.proxool.ConnectionPool:run---Unknown Source:
               d1-HouseKeeper
                       method:: java.lang.Thread:sleep---Native Method:
                       method:: org.logicalcobwebs.proxool.ConnectionPool:run---Unknown Source:
                       method:: java.lang.Thread:run---Thread.java:536
        

· 并排显示采用多个dump的线程信息---并且当我们处于其上时,高亮显示不同的状态。

(样式表用于高亮信息的XML文件 --> 完整结果的 HTML页面)

hm_xml_sun_141.gif

· 使用Graphviz来显示锁定,这些锁定是在基于Sun 1.4.1 JVM锁定行的dump中找到的(两阶段转换)

(样式表 --> 生成 GraphViz .dot 文件 {此处是 dot.txt} --> 完整的映像 {700K} )

real-life-showlocks-small.gif

注意,如果你将检查整个映像,在95个线程中只有12个被显示出来。转换脚本自动标识和隔离那些参与了多线程锁定生成的线程。别的线程也有可能处于锁定状态(例如,Object.wait()方法等待显式的notify()调用),但是由于从thread-dump中无法为它们析取出有用的关系,所以它们在此并不会显示出来。其他转换在分析这些线程流时更有用。


仅此而已吗?
那么,所有这些例子都可以在thread-dump的XML表示中解决吗?远远不是这样。本文所给出的转换只是采用最新的thread-dump信息完成工作的一个简单实例。尽量释放你的创造力,下面是其他的几种可能性:
· 在highlight.xsl例子中建立样式查找文档,以不同的颜色显示不同的应用层(如Web,EJB,JDBC等),并且在应用程序花费时间的地方做好标记。
· 将thread-dump的单独行连接到Source 或是JavaDoc Browser。
· 采用动作而不是名称来对线程分组。
· 从已编译的类中提取出锁定信息,并将其与缺乏锁定信息的thread-dump结合起来,以便进行更高级的分析。
· 通过将thread-dump转换到SVG来激活它。
· 使用XSLT将信息转换至中间格式,而其他工具接着便可以处理这一中间格式(正如上文提及的显示锁定的例子)。
现在,请你自己来尝试一下。

结束语
通过将多种thread-dump格式转换成统一的XML格式,我们可以大大简化thread-dump分析工作的可移植性,并且可使先前隐藏在大量数据中的关系显现出来。另外,由于与Java thread-dump相比而言,在XML/XSLT方面有更多有工具和专家,因此,更多的人们可以加入到创建有用的统计数据和可视化结果的行列中来。

 作者简介
Alexandre Rafalovitch是BEA在澳大利亚悉尼的高级开发者关系工程师,他有13年的软件开发和技术支持经验。他是Sun认证的Java程序员、BEA WebLogic认证开发者以及内部四项认证管理员(资深技术)。Alexandre目前主要专注于WebLogic Server和构建用于内部和外部技术支持的工具。

转载于:https://www.cnblogs.com/kapok/archive/2005/10/15/255398.html

おすすめ

転載: blog.csdn.net/weixin_30411997/article/details/94783383