激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - 深入JVM剖析Java的線程堆棧

深入JVM剖析Java的線程堆棧

2019-12-25 13:39goldensun JAVA教程

這篇文章主要介紹了深入JVM剖析Java的線程堆棧,Java中的堆內(nèi)存和堆棧原理的應(yīng)用等知識(shí)是深入學(xué)習(xí)Java的重點(diǎn),需要的朋友可以參考下

在這篇文章里我將教會(huì)你如何分析JVM的線程堆棧以及如何從堆棧信息中找出問題的根因。在我看來線程堆棧分析技術(shù)是Java EE產(chǎn)品支持工程師所必須掌握的一門技術(shù)。在線程堆棧中存儲(chǔ)的信息,通常遠(yuǎn)超出你的想象,我們可以在工作中善加利用這些信息。

我的目標(biāo)是分享我過去十幾年來在線程分析中積累的知識(shí)和經(jīng)驗(yàn)。這些知識(shí)和經(jīng)驗(yàn)是在各種版本的JVM以及各廠商的JVM供應(yīng)商的深入分析中獲得的,在這個(gè)過程中我也總結(jié)出大量的通用問題模板。

那么,準(zhǔn)備好了么,現(xiàn)在就把這篇文章加入書簽,在后續(xù)幾周中我會(huì)給大家?guī)磉@一系列的專題文章。還等什么,請(qǐng)趕緊給你的同事和朋友分享這個(gè)線程分析培訓(xùn)計(jì)劃吧。

聽上去是不錯(cuò),我確實(shí)是應(yīng)該提升我的線程堆棧分析技能...但我要從哪里開始呢?

我的建議是跟隨我來完成這個(gè)線程分析培訓(xùn)計(jì)劃。下面是我們會(huì)覆蓋到的培訓(xùn)內(nèi)容。同時(shí),我會(huì)把我處理過的實(shí)際案例分享給大家,以便與大家學(xué)習(xí)和理解。

1) 線程堆棧概述及基礎(chǔ)知識(shí)
2) 線程堆棧的生成原理以及相關(guān)工具
3) 不同JVM線程堆棧的格式的差異(Sun HotSpot、IBM JRE、Oracal JRockit)
4) 線程堆棧日志介紹以及解析方法
5) 線程堆棧的分析和相關(guān)的技術(shù)
6) 常見的問題模板(線程竟態(tài)、死鎖、IO調(diào)用掛死、垃圾回收/OutOfMemoryError問題、死循環(huán)等)
7) 線程堆棧問題實(shí)例分析

我希望這一系列的培訓(xùn)能給你帶來確實(shí)的幫助,所以請(qǐng)持續(xù)關(guān)注每周的文章更新。

但是如果我在學(xué)習(xí)過程中有疑問或者無法理解文章中的內(nèi)容該怎么辦?

不用擔(dān)心,把我當(dāng)做你的導(dǎo)師就好。任何關(guān)于線程堆棧的問題都可以咨詢我(前提是問題不能太low)。請(qǐng)隨意選擇下面的幾種方式與我取得聯(lián)系:

1) 直接本文下面發(fā)表評(píng)論(不好意思的話可以匿名)
2) 將你的線程堆棧數(shù)據(jù)提交到Root Cause Analysis forum
3) 發(fā)Email給我,地址是 @[email protected]

能幫我分析我們產(chǎn)品上遇到的問題么?

當(dāng)然可以,如果你愿意的話可以把你的堆棧現(xiàn)場(chǎng)數(shù)據(jù)通過郵件或論壇 Root Cause Analysis forum發(fā)給我。處理實(shí)際問題是才是學(xué)習(xí)提升技能的王道。

我真心期望大家能夠喜歡這個(gè)培訓(xùn)。所以我會(huì)盡我所能去為你提供高質(zhì)量的材料,并回答大家的各種問題。

在介紹線程堆棧分析技術(shù)和問題模式之前,先要給大家講講基礎(chǔ)的內(nèi)容。所以在這篇帖子里,我將先覆蓋到最基本的內(nèi)容,這樣大家就能更好的去理解JVM、中間件、以及Java EE容器之間的交互。

Java VM 概述

Java虛擬機(jī)是Jave EE 平臺(tái)的基礎(chǔ)。它是中間件和應(yīng)用程序被部署和運(yùn)行的地方。

JVM向中間件軟件和你的Java/Java EE程序提供了下面這些東西:

–   (二進(jìn)制形式的)Java / Java EE 程序運(yùn)行環(huán)境
–   一些程序功能特性和工具 (IO 基礎(chǔ)設(shè)施,數(shù)據(jù)結(jié)構(gòu),線程管理,安全,監(jiān)控 等等.)
–   借助垃圾回收的動(dòng)態(tài)內(nèi)存分配與管理

你的JVM可以駐留在許多的操作系統(tǒng) (Solaris, AIX, Windows 等等.)之上,并且能根據(jù)你的物理服務(wù)器配置,你可以在每臺(tái)物理/虛擬服務(wù)器上安裝1到多個(gè)JVM進(jìn)程.

JVM與中間件之間的交互

下面這張圖展示了JVM、中間件和應(yīng)用程序之間的高層交互模型。

深入JVM剖析Java的線程堆棧

圖中展示的JVM、中間件和應(yīng)用程序件之間的一些簡單和典型的交互。如你所見,標(biāo)準(zhǔn)Java EE應(yīng)用程序的線程的分配實(shí)在中間件內(nèi)核與JVM之間完成的。(當(dāng)然也有例外,應(yīng)用程序可以直接調(diào)用API來創(chuàng)建線程,這種做法并不常見,而且在使用的過程中也要特別的小心)

同時(shí),請(qǐng)注意一些線程是由JVM內(nèi)部來進(jìn)行管理的,典型的例子就是垃圾回收線程,JVM內(nèi)部使用這個(gè)線程來做并行的垃圾回收處理。

因?yàn)榇蠖鄶?shù)的線程分配都是由Java EE容器完成的,所以能夠理解和認(rèn)識(shí)線程堆棧跟蹤,并能從線程堆棧數(shù)據(jù)中識(shí)別出它來,對(duì)你而言很重要. 這可以讓你能夠快速的知道Java EE容器正要執(zhí)行的是什么類型的請(qǐng)求.

從一個(gè)線程轉(zhuǎn)儲(chǔ)堆棧的分析角度來看,你將能了解從JVM發(fā)現(xiàn)的線程池之間的不同,并識(shí)別出請(qǐng)求的類型.

最后一節(jié)會(huì)向你提供對(duì)于HotSop VM而言什么是JVM線程堆棧的一個(gè)概述,還有你將會(huì)遇到的各種不同的線程. 而對(duì) IBM VM 線程堆棧形式詳細(xì)內(nèi)容將會(huì)在第四節(jié)向你提供.

請(qǐng)注意你可以從根本原因分析論壇獲得針對(duì)本文的線程堆棧示例.

JVM 線程堆棧——它是什么?

JVM線程堆棧是一個(gè)給定時(shí)間的快照,它能向你提供所有被創(chuàng)建出來的Java線程的完整清單.

每一個(gè)被發(fā)現(xiàn)的Java線程都會(huì)給你如下信息:

– 線程的名稱;經(jīng)常被中間件廠商用來識(shí)別線程的標(biāo)識(shí),一般還會(huì)帶上被分配的線程池名稱以及狀態(tài) (運(yùn)行,阻塞等等.)

      – 線程類型 & 優(yōu)先級(jí),例如 : daemon prio=3 ** 中間件程序一般以后臺(tái)守護(hù)的形式創(chuàng)建他們的線程,這意味著這些線程是在后臺(tái)運(yùn)行的;它們會(huì)向它們的用戶提供服務(wù),例如:向你的Java EE應(yīng)用程序 **

       – Java線程ID,例如 : tid=0x000000011e52a800 ** 這是通過 java.lang.Thread.getId() 獲得的Java線程ID,它常常用自增長的長整形 1..n** 實(shí)現(xiàn)


       – 原生線程ID,例如 : nid=0x251c** ,之所以關(guān)鍵是因?yàn)樵€程ID可以讓你獲得諸如從操作系統(tǒng)的角度來看那個(gè)線程在你的JVM中使用了大部分的CPU時(shí)間等這樣的相關(guān)信息. **

       – Java線程狀態(tài)和詳細(xì)信息,例如: waiting for monitor entry [0xfffffffea5afb000] java.lang.Thread.State: BLOCKED (on object monitor)
** 可以快速的了解到線程狀態(tài)極其當(dāng)前阻塞的可能原因 **

        – Java線程棧跟蹤;這是目前為止你能從線程堆棧中找到的最重要的數(shù)據(jù). 這也是你花費(fèi)最多分析時(shí)間的地方,因?yàn)镴ava棧跟蹤向提供了你將會(huì)在稍后的練習(xí)環(huán)節(jié)了解到的導(dǎo)致諸多類型的問題的根本原因,所需要的90%的信息。


        – Java 堆內(nèi)存分解; 從HotSpot VM 1.6版本開始,在線程堆棧的末尾處可以看到HotSpot的內(nèi)存使用情況,比如說Java的堆內(nèi)存(YoungGen, OldGen) & PermGen 空間。這個(gè)信息對(duì)分析由于頻繁GC而引起的問題時(shí),是很有用的。你可以使用已知的線程數(shù)據(jù)或模式做一個(gè)快速的定位。
 

?
1
2
3
4
5
6
7
8
9
Heap
PSYoungGen   total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)
eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)
from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)
to  space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)
PSOldGen    total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)
object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)
PSPermGen    total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)
object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee0400000)

線程堆棧信息大拆解

為了讓大家更好的理解,給大家提供了下面的這張圖,在這張圖中將HotSpot VM上的線程堆棧信息和線程池做了詳細(xì)的拆解,如下圖所示:

深入JVM剖析Java的線程堆棧

上圖中可以看出線程堆棧是由多個(gè)不同部分組成的。這些信息對(duì)問題分析都很重要,但對(duì)不同的問題模式的分析會(huì)使用不同的部分(問題模式會(huì)在后面的文章中做模擬和演示。)


現(xiàn)在通過這個(gè)分析樣例,給大家詳細(xì)解釋一下HoteSpot上線程堆棧信息中的各個(gè)組成部分:

?
1
# Full thread dump標(biāo)示符

“Full thread dump”是一個(gè)全局唯一的關(guān)鍵字,你可以在中間件和單機(jī)版本Java的線程堆棧信息的輸出日志中找到它(比如說在UNIX下使用:kill -3 <PID> )。這是線程堆棧快照的開始部分。
 
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.0-b11 mixed mode):

# Java EE 中間件,第三方以及自定義應(yīng)用軟件中的線程

這個(gè)部分是整個(gè)線程堆棧的核心部分,也是通常需要花費(fèi)最多分析時(shí)間的部分。堆棧中線程的個(gè)數(shù)取決你使用的中間件,第三方庫(可能會(huì)有獨(dú)立線程)以及你的應(yīng)用程序(如果創(chuàng)建自定義線程,這通常不是一個(gè)很好的實(shí)踐)。


在我們的示例線程堆棧中,WebLogic是我們所使用的中間件。從Weblogic 9.2開始, 會(huì)使用一個(gè)用“'weblogic.kernel.Default (self-tuning)”唯一標(biāo)識(shí)的能自行管理的線程池
 

?
1
2
3
4
5
6
7
8
"[STANDBY] ExecuteThread: '414' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=3 tid=0x000000010916a800 nid=0x2613 in Object.wait() [0xfffffffe9edff000]
  java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)
    at java.lang.Object.wait(Object.java:485)
    at weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:160)
    - locked <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)

# HotSpot VM 線程
這是一個(gè)有Hotspot VM管理的內(nèi)部線程,用于執(zhí)行內(nèi)部的原生操作。一般你不用對(duì)此操太多心,除非你(通過相關(guān)的線程堆棧以及 prstat或者原生線程Id)發(fā)現(xiàn)很高的CPU占用率.
 

?
1
"VM Periodic Task Thread" prio=3 tid=0x0000000101238800 nid=0x19 waiting on condition

# HotSpot GC 線程
當(dāng)使用 HotSpot 進(jìn)行并行 GC (如今在使用多個(gè)物理核心的環(huán)境下很常見), 默認(rèn)創(chuàng)建的HotSpot VM 或者每個(gè)JVM管理一個(gè)有特定標(biāo)識(shí)的GC線程時(shí). 這些GC線程可以讓VM以并行的方式執(zhí)行其周期性的GC清理, 這會(huì)導(dǎo)致GC時(shí)間的總體減少;與此同時(shí)的代價(jià)是CPU的使用時(shí)間會(huì)增加.
 

?
1
2
3
"GC task thread#0 (ParallelGC)" prio=3 tid=0x0000000100120000 nid=0x3 runnable
"GC task thread#1 (ParallelGC)" prio=3 tid=0x0000000100131000 nid=0x4 runnable
………………………………………………………………………………………………………………………………………………………………


這事非常關(guān)鍵的數(shù)據(jù),因?yàn)楫?dāng)你遇到跟GC有關(guān)的問題,諸如過度GC、內(nèi)存泄露等問題是,你將可以利用這些線程的原生Id值關(guān)聯(lián)的操作系統(tǒng)或者Java線程,進(jìn)而發(fā)現(xiàn)任何對(duì)CPI時(shí)間的高占用. 未來的文章你將會(huì)了解到如何識(shí)別并診斷這樣的問題.

# JNI 全局引用計(jì)數(shù)
JNI (Java 本地接口)的全局引用就是從本地代碼到由Java垃圾收集器管理的Java對(duì)象的基本的對(duì)象引用. 它的角色就是阻止對(duì)仍然在被本地代碼使用,但是技術(shù)上已經(jīng)不是Java代碼中的“活動(dòng)的”引用了的對(duì)象的垃圾收集.

同時(shí)為了偵測(cè)JNI相關(guān)的泄露而留意JNI引用也很重要. 如果你的程序直接使用了JNI,或者像監(jiān)聽器這樣的第三方工具,就容易造成本地的內(nèi)存泄露.
 
JNI global references: 1925

# Java 堆棧使用視圖


這些數(shù)據(jù)被添加回了 JDK 1 .6 ,向你提供有關(guān)Hotspot堆棧的一個(gè)簡短而快速的視圖. 我發(fā)現(xiàn)它在當(dāng)我處理帶有過高CPU占用的GC相關(guān)的問題時(shí)非常有用,你可以在一個(gè)單獨(dú)的快照中同時(shí)看到線程堆棧以及Java堆的信息,讓你當(dāng)時(shí)就可以在一個(gè)特定的Java堆內(nèi)存空間中解析(或者排除)出任何的關(guān)鍵點(diǎn). 你如在我們的示例線程堆棧中所見,Java 的堆 OldGen 超出了最大值!
 

?
1
2
3
4
5
6
7
8
9
Heap
 PSYoungGen   total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)
 eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)
 from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)
 to  space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)
 PSOldGen    total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)
 object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)
 PSPermGen    total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)
 object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee040000

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 黄色美女视频网站 | 久久久久久久久久久久99 | 91麻豆精品国产91久久久更新资源速度超快 | 国产精品久久99精品毛片三a | 99久久视频 | 欧美一区二区网站 | 全网免费毛片 | 国产亚洲精品久久777777 | 日韩午夜片 | 一级做受毛片免费大片 | 欧美成人视 | 新久久久久久 | 水卜樱一区二区av | 懂色粉嫩av久婷啪 | 一级啪啪片 | 91精品国产综合久久婷婷香 | 久久久一区二区三区视频 | 国产精品美女久久久免费 | 在线播放免费播放av片 | 成人9禁啪啪无遮挡免费 | 蜜桃一本色道久久综合亚洲精品冫 | 51色视频 | 久久久久久久一区二区 | 一级毛片免费大片 | 毛片视频免费观看 | 毛片午夜 | 成年免费观看视频 | 亚洲人成中文字幕在线观看 | 久久久国产精品成人免费 | 国产成人小视频在线观看 | 欧美国产日韩在线 | 亚欧美一区二区 | 久久久久久久国产视频 | 久久精品综合视频 | 亚州精品天堂中文字幕 | 欧美亚洲一级 | 久久99精品久久久久久国产越南 | 久久综合伊人 | 国产一区二区三区影视 | 国产精品久久久久久久久久大牛 | 97视频 |