java dump分析工具_Java 性能分析工具 (2):Java 內置監控工具

cc8d51e5daf3623311938a5f5e98de78.png

引言

本文為 Java 性能分析工具系列文章第二篇,第一篇:操作系統工具。在本文中將介紹如何使用 Java 內置監控工具更加深入的了解 Java 應用程序和 JVM 本身。在 JDK 中有許多內置的工具,其中包括:

  • jcmd:打印一個 Java 進程的類,線程以及虛擬機信息。適合用在腳本中。使用 jcmd - h 來查看使用方法。
  • jconsole:提供 JVM 活動的圖形化展示,包括線程使用,類使用以及垃圾回收(GC)信息。
  • jhat:幫助分析內存堆存儲。
  • jmap:提供 JVM 內存使用信息,適用于腳本中。
  • jinfo:訪問 JVM 系統屬性,同時可以動態修改這些屬性。
  • jstack:提供 Java 進程內的線程堆棧信息。
  • jstat:提供 Java 垃圾回收以及類加載信息。
  • jvisualvm:監控 JVM 的可視化工具,剖析運行中的應用程序,分析 JVM 堆存儲。

下面將根據功能劃分來詳細介紹這些工具。

VM 基本信息

JVM 工具能夠提供一個運行中的 JVM 進程的基本信息,例如運行時間、使用中的 JVM 參數以及 JVM 系統屬性。

  • uptimeJVM 運行的時間,jcmd process_id VM.uptime
  • system properties通過 System.getProperties() 可以得到的系統屬性也可以通過下面的命令獲得:

jcmd process_id VM.system_properties 或者 jinfo –sysprops process_id

這些屬性包括所有通過命令行-D 選項設置的屬性、應用程序動態添加的屬性和 JVM 的默認屬性。

  • JVM version通過 jcmd process_id VM.version 獲得。
  • JVM command lineJVM 命令行可以在 jconsole 中的 VM summary 中找到,或者通過 jcmd process_id VM.command_line 命令獲得。
  • JVM 調優參數通過命令 jcmd process_id VM.flags [-all] 命令或者所有生效的調優參數獲得。

使用調優參數(Tuning Flags)

由于調優參數非常繁多,需要借助 JVM 命令行和 JVM 調優參數來使用。使用 command_line 命令可以獲得命令行中指定的調優參數,flags 命令可以獲得通過命令設置的調優參數和 JVM 設置的調優參數。

通過 jcmd 命令可以獲得一個運行中 JVM 內生效的調優參數。通過下面這條命令可以獲得一個指定平臺內生效的調優參數。

java 

我們需要把其他選項同時包含在這條命令中,尤其是設置了 GC 相關的調優參數。這條命令的部分輸出如下所示,第一行中的冒號說明第一行的調優參數使用的不是默認值,而是以下三種方式設置:

  1. 通過命令行設置其他選項間接改變了此調優參數的值
  2. JVM 計算出默認值第二行由于沒有包含冒號,說明此行的調優參數為當前 JVM 版本的默認值,最后一列的 product 說明此行的調優參數的值在不同平臺相同,而 pd product 說明此行的調優參數的值依賴于平臺。
uintx 

最后一列的其他選項:

manageable

jinfo 命令可以查看某個單一 flag 的值,通過下面的命令:

jinfo 

3.通過下面的命令可以設置某個 flag 的 manageable 屬性來控制其能否在運行時被改變:

jinfo 

盡管 jinfo 命令可以改變任何 flag 的值,但不能確定 JVM 會接受這些改變。例如很多影響垃圾回收算法執行的 flag 都會在 JVM 啟動時被設置,在 JVM 運行過程中通過 jinfo 命令修改 flag 的值并不會影響算法執行。所有此命令只對那些 manageable 為真的 flag 起作用。

線程信息

jconsole 和 jvisualvm 命令可以幫助開發人員剖析應用程序運行過程中線程的相關信息。通過 jstack process_id 命令可以查看線程的運行時棧信息,可以明確獲得當前線程是否被阻塞。通過命令 jcmd process_id Thread.print 可以獲得相同結果。

類信息

通過 jconsole 和 jstat 命令可以獲得應用程序運行過程中的所有類的相關信息,同時 jstat 命令也提供了類編譯的相關信息。

垃圾回收信息

Jconsole 展示了 JVM 堆使用的情況,它所繪制的的動態圖能夠幫助開發人員了解堆的內部情況。jcmd 支持垃圾回收操作。jmap 提供堆信息總覽。jstat 從不同的角度展示垃圾回收是如何工作的。

Heap Dump 文件的后序處理

通過 jvisualvm 用戶界面可以得到 Heap Dump 文件,通過 jcmd 和 jmap 也可以獲得。Heap Dump 文件是堆的快照,一般使用 jvisualvm 和 jhat 來分析這個快照。

性能分析工具

Java 提供的性能分析器是最重要的分析工具。它的種類繁多,各有所長,使用不同的分析器在分析同一個應用時可能會發現不同的問題。在使用過程中需要各取所長,這樣才能對應用進行全面的分析。

基本上所有的 Java 性能分析器都是用 Java 實現的,通過套接字(socket)與被分析應用進行通信來獲得被分析應用的運行信息。需要注意的是,在使用性能分析工具調優被分析應用的同時,需要關注性能分析器其自身的性能。假如當被分析的應用程序產生十分龐大的信息,而將其發送至性能分析器時,如果性能分析器沒有空間充分管理高效的內存堆來處理這些信息時,分析將無法進行。采用并行垃圾回收算法進行內存管理是當前性能分析器比較流行的做法,這種算法能夠最大程度地降低內存溢出的可能。

性能分析分為采樣模式和檢測模式。下面將分別介紹這兩種模式。

采樣分析

采樣模式是性能分析中最常用的模式,因為其對被分析應用程序影響最小,這一點非常重要。只有當性能分析過程對應用程序的影響降到最低,才能獲得有價值的性能分析結果。

在采樣分析模式中,分析器被定時觸發工作。在工作周期內,分析器依次檢查每個線程并記錄線程中正在運行的方法,在某些特定場景下,采樣分析往往會帶來錯誤的分析結果。例如,在圖 1 中,某線程在一段時間內交替執行方法 A 和方法 B,每次當分析器被觸發工作時,該線程都恰好在執行方法 B,那么分析器會認為該線程的所有時間都是在執行方法 B,但是事實并非如此,該線程執行方法 A 的時間遠大于執行方法 B 的時間,只是并未被分析器采樣到。

圖 1. 某一時間段內線程交替執行方法 A 和 B 示例圖

bcd4839162828ca50cd25fdd0b7a1ac7.png

這是采樣模式中最常見的錯誤,通過增加采樣分析器的采樣時間隔可以幫助我們有效的減少這類錯誤的發生,因為時間間隔太小往往會增加采樣分析器對被分析的應用程序產生性能方面的影響,從而導致分析結果失真。所以時間間隔需要根據被分析應用的特點通過多次的試驗以及經驗來決定,權衡過大或過小的影響之后設定。

圖 2. 采樣模式分析示例圖

ee3f0943b95760854c81693ad90e040c.png

圖 2 所示是使用采樣模式分析一個應用服務器 GlassFish 啟動過程的結果。從圖中可以看到,方法 defineClass1() 使用了 19%的時間,接下來是方法 getPackageSourceInternal(),占用了 10%的時間。Java 應用程序中定義的類會影響應用程序啟動過程中的性能表現,為了提高應用程序的啟動速度,就必須通過提高類加載的速度,從而達到提升啟動速度的目標。從圖中我們可能會錯誤的認為要改善性能的方法是 defineClass1(),但是 defineClass1() 其實是 JDK 中的方法,我們不可能通過重寫 JVM 來提高它的性能。即使重寫此方法將其執行時間優化至原有時間的 60%,也只能減少 10%應用程序整體運行時間,這顯然得不償失。

檢測分析

相比于采樣模式,檢測模式是要侵入被分析的應用程序內部,雖然這樣做并不是高效、友好的,但它卻可以獲得非常有價值的信息。圖 3 為使用相同分析工具的檢測模式分析相同應用服務器 GlassFish 的結果。

圖 3. 檢測分析示例圖

cec105ceecc1a0021a7f36d2b21c12f8.png

在圖中有以下幾點信息:

  1. 最耗時的方法為 getPackageSourcesInternal(), 占用了 13%的時間,而并非在采樣模式中得到的 4%;
  2. 方法 defineClaass1() 并未出現在分析結果中。
  3. 分析結果中包括每個方法執行的次數和平均耗時。

這些分析結果中的信息對于發現耗時多的代碼是非常有幫助的。在本例中,盡管方法 ImmutableMap.get() 消耗 12%的時間,但是它被調用了四百七十萬次之多。如果減少此方法的調用次數,應用的性能將會得到大幅度提升。

檢測分析器在類被加載時通過改變其字節碼順序來獲取應用運行數據,例如增加記錄方法被調用次數的代碼。相比于采樣模式,這種方式會更大程度的影響應用本身的性能。例如,JVM 會根據方法的代碼塊大小,將方法體很小的方法內聯化,這樣在內聯方法執行時就不會進行方法調用。在檢測分析器在內聯方法中加入其代碼后,此方法因為方法體過大并未被 JVM 內聯化,由此造成此方法的耗時被放大。內聯化只是一個例子,當越來越多的代碼被改變的時候,分析的結果失真的概率就會比較大。

造成方法 ImmutableMap.get() 沒有出現在采樣模式分析結果中的原因是安全點(safepoint)的存在。只有當一個線程獲得的內存大于安全點時,采樣分析器才會對其進行分析。因為方法 ImmutableMap.get() 所在線程一直沒有達到安全點,所以在結果中不會出現。當使用采樣模式安全點過高時,會低估一些方法對性能的影響。

在本例中,無論是采樣分析還是檢測分析,都能發現應用的性能瓶頸在于類的加載和解析。但是在實際中,不同的分析器不可能得出完全相同的分析結果。分析器擅長估量,但也只是估量,一些誤差甚至是錯誤不可避免,所以在性能分析過程中還需要我們更加靈活的使用分析器。

阻塞方法和線程的時間軸

如圖 4 所示為使用 NetBeans Profiler(另一種檢測分析器)分析上述應用服務器 GlassFish 啟動過程的結果展示。在此結果中,方法 park(),parkNanos() 和 read() 占用了絕大多數的應用運行時間。這些方法都是被阻塞的方法,并不消耗 CPU,所以在計算應用的 CPU 使用率時這些時間不應計入。應用中的線程并沒有使用 632 秒來執行 parkNanos() 方法,而是等待其他操作完成花費 632 秒。park() 和 read() 方法與此同理。

圖 4. NetBeans 檢測分析示例圖

948413e806f88a8a09c989f1f129cf60.png

因此,大多數的分析器都不會將被阻塞的方法和閑置的線程計入結果。在 NetBeans 中,可以設置分析結果包含所有的方法,所以在本例中這些方法被計入結果。在本例中,執行 park() 方法的線程位于服務器線程池中,當服務器接收到請求時,這些線程處理請求。當沒有請求時,這些線程處于阻塞狀態,等到新的請求,并不占用 CPU。這是應用服務器的正常狀態。

絕大多數的基于 Java 的分析器都可以提供過濾器功能來查看或者隱藏被阻塞方法調用的時間,如果需要可以使用該功能。通常情況下,查看線程的運行狀況比查看被阻塞方法的阻塞時間更加有幫助。

圖 5. Oracle Solaris Studio 中線程的運行示例圖

e2f7712dc1ea6b79bc346ad4de4c9f62.png

圖 5 為在 Oracle Solaris Studio 中一個線程的運行情況。每一個水平區域代表一個不同的線程,所以上圖中有兩個線程(1.3 和 1.2)。不同顏色的柱子代表執行的不同方法;空白處代表該線程沒有執行任何方法。綜合來看,線程 1.2 先執行了一段代碼然后等待線程 1.3 完成執行,線程 1.3 完成執行后等待線程 1.2 執行另一段代碼。深入下去可以發現這些線程如何進行交互。

圖中存在一些沒有線程執行的空白區域,這是因為圖中只展示了其中的兩個線程,所以在那段空白區域是圖中所示兩個線程在等待其他線程執行完成。

本地分析器

本地分析器是用來分析 JVM 本身的工具。通過本地分析器可以觀察到 JVM 正在進行的操作或者查看是否有應用程序包含了 JVM 的本地庫,也可以觀察到代碼內部。任何本地分析器都可以分析使用 C 語言實現的 JVM(包括所有本地庫),但是一些本地分析其不能分析使用 Java 和 C++實現的應用。

圖 6. 本地分析器分析示例圖

a7573c9c7c08cdbb41b2e8eba68e4d32.png

圖 6 中展示了使用 Oracle Solaris Studio 分析器中分析 GlassFish 啟動過程的結果。Oracle Solaris Studio 是一個可以分析 Java 和 C++的本地分析器。從圖中可以發現,應用消耗的 CPU 時間為 25.1 秒。其中 JVM-System 消耗 20 秒,包括 JVM 編譯器線程,垃圾回收線程以及一些輔助線程。由于在啟動過程中需要編譯非常多的代碼,所以 JVM 編譯器線程消耗了絕大多數時間,而垃圾回收線程只消耗了很少的時間。

通過本地分析器我們不僅可以分析優化 JVM 自身功能,更重要的是可以獲得應用程序進行垃圾回收的時間。在 Java 分析工具中,垃圾回收線程的信息是無法得到的。

分析過 JVM 本地代碼后,我們將對應用程序的啟動過程進行分析。如圖 7 所示,繼在采樣模式分析后,方法 defineclass1() 又一次被分析為最耗時的方法。值得關注的是,再次分析結果中,解壓讀取 jar 文件的方法耗時相對較多。類加載中會用到這些方法,所以證明優化的方向是正確的。由于 Java zip 庫中引用的本地代碼在其他分析工具中被作為阻塞方法調用,所以在上文各類工具中并沒有發現此方法。

圖 7. 采樣模式分析示例圖

ff9b348a26599eefc3eb01610d5849b7.png

無論使用何種性能分析工具,最重要的是熟悉每種工具的優勢和劣勢。這樣才能取長補短,配合使用。開發人員必須學會如何使用性能分析器來找到性能瓶頸,找到需要優化的代碼,而不是單純的關注最耗時的個別方法。

總結

基于采樣的性能分析是最常見的一種,因為其相對能做到的分析是有限的,亦或者分析過程所能搜集到的信息是概述性的,往往并不能真實表現應用程序內部的運行情況,但是其分析過程中引入的工作量通常是較低的。不同的采樣分析工具行為是不同的,充分利用其優勢,做有針對性的分析才是最有意義的。

檢測分析能夠獲得非常多的有關應用程序內部信息,但是前期準備工作往往是非常大的。檢測分析方法應當盡量應用在一小節代碼中,或者少數幾個類、包中。這種方法其實一定程度上限制了對整體應用程序的性能分析,僅適合在程序單元中使用,點對點,針對性較強的分析,采用檢測分析的時候,更多時間要求開發人員明確知道哪里有可能產生性能瓶頸。

線程阻塞不一定就是代碼編寫而產生的,發生線程阻塞時,更多的建議是去想,去看為什么會被阻塞,而不是直接查看代碼。盡量采用線程執行時間軸的分析方法。

本地分析提供了既可以深入查看 JVM 內部,同時也可以查看應用程序代碼執行的情況。

如果本地分析顯示在 GC 過程中大量的使用 CPU 資源,那么調優收集器就是必要的。需要提醒大家的是,編譯線程通常是不影響應用程序的性能。

原作者:李 偉軍, 宋 翰瀛, 和 楊 翔宇
原文鏈接:Java 性能分析工具 , 第 2 部分:Java 內置監控工具
原出處:IBM Developer

9c98a31ce99135c93f1794d7ae1fd016.gif

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454256.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454256.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454256.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux+php+memcache+APC加速PHP網站

一、前言對于一個站長而言不僅要做好網站內容外,還需要對網站做優化,如果速度訪問很慢的,沒有人下次再訪問你的站點,目前國內使用php的網站不計其數,這里用我的博客為例:http://chinaapp.sinaapp.com 以加速…

為機器學習占地13

是將若干個學習習 弱分類器間存在一定的差異性,這會導致分類的邊界不同,也就是說可能存在錯誤。那么將多個弱分類器合并后,就可以得到更加合理的邊界,減少整體的錯誤率,實現更好的效果; 對于數據集過大或者…

Python面試題(第二篇)

第二部分 網絡編程和并發(34題)1、簡述 OSI 七層協議。2、什么是C/S和B/S架構?3、簡述 三次握手、四次揮手的流程。4、什么是arp協議?5、TCP和UDP的區別?6、什么是局域網和廣域網?7、為何基于tcp協議的通信…

noip模擬賽 radius

分析:這道題實在是不好想,一個可以騙分的想法是假定要求的那個點在中心點上,可以騙得不少分.但是在邊上的點要怎么確定呢?理論復雜度O(﹢無窮).答案一定是和端點有關的,涉及到最大值最小,考慮二分最大值&…

來自IT公司速查手冊的各大IT公司薪資和待遇內幕

來自IT公司速查手冊的各大IT公司薪資和待遇內幕 (轉載于 http://xuchaoyi99.cnblogs.com/ ) 編號 1. 杭州 諾基亞 2. 南京 趨勢科技 Trend 3. 北京 聯想(北京)有限公司 4. 深圳 華為 5. 深圳 中興通訊 6. 上海 SAP 7.…

Docker 精通之 Dockerfile

Docker 精通系列 Docker 精通之入門Docker 精通之微服務Docker 精通之常用命令Docker 精通之 Dockerfile 1.基本說明 Dockfile 是一個用于編寫 docker 鏡像生成過程的文件,其有特定的語法。在一個文件夾中,如果有一個名字為 Dockfile 的文件&#xff0c…

c語言中int的取值范圍_c語言入門(1)

c語言入門C語言一經出現就以其功能豐富、表達能力強、靈活方便、應用面廣等特點迅速在全世界普及和推廣。C語言不但執行效率高而且可移植性好,可以用來開發應用軟件、驅動、操作系統等。C語言也是其它眾多高級語言的鼻祖語言,所以說學習C語言是進入編程世…

vue : 無法將“vue”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保路徑正確, 然后再試一次。

vue : 無法將“vue”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保路徑正確, 然后再試一次。 報錯原因: 沒有安裝腳手架vue-cli 解決方法:安裝腳手架vue-cli npm inst…

session的生命周期

session的生命周期分為創建、活動、銷毀三個階段 創建一個新的會話不代表舊的會話就銷毀了 session.invalidate()方法可以銷毀當前會話 在page1中寫上這個方法再打開網頁 說明該會話被銷毀了出現了錯誤 我們把這個方法寫在所有代碼段的下面 再打開這個網頁 刷新網頁 這個sessio…

虛擬化與網絡

本文轉自Grodd51CTO博客,原文鏈接:http://blog.51cto.com/juispan/1959791,如需轉載請自行聯系原作者

算法基礎之搜索和經典排序

目錄 簡介 搜索算法 二分法查找 排序算法 冒泡排序(Bubble Sort) 選擇排序(Selection Sort) 插入排序(Insert Sort) 快速排序(Quick Sort) 歸并排序(Merge Sort…

IT人不要一直做技術

發表于:2009-03-04 09:51:44 樓主IT人不要一直做技術 【引子】感覺這篇文章很有深意,正是我所想說的話。希望大家有借鑒。 【原文】 我現在是自己做,但我此前有多年在從事軟件開發工作,當回過頭來想一想自己,覺得特別…

背景寬高隨文本變化_中科大提出ContourNet:更準確的任意形狀場景文本檢測新方法...

點擊上方“CVer”,選擇加"星標"置頂重磅干貨,第一時間送達本文轉載自:CSIG文檔圖像分析與識別專委會本文簡要介紹2020年被CVPR錄用的論文“ContourNet: Taking a Further Step toward Accurate Arbitrary-shaped Scene Text Detect…

python 類、模塊、包的區別

學習python的時候,碰到了import 和 from xx import xx的問題, 為了弄清楚什么是 module 和package ,這篇文章講解的不錯!! 原文: http://www.cnblogs.com/kex1n/p/5977051.html --------------------------…

Hadoop MapReduce概念學習系列之MPI和MapReduce(十三)

在當前最流行的高性能并行體系結構中比較常用的并行編程環境分為兩類:消息傳遞和共享存儲。MPI是基于消息傳遞的經典代表,是消息傳遞井行程序設計的標準,用于構建高可靠的、可伸縮的、靈活的分布式應用程消息傳遞井行處理開銷比較大,適合于大…

算法面試題匯總(更新中)

1、根據數字返回相應位置數字 def get_digit(num, i):# i0 個位 1 十位 2 百位...return num // (10 ** i) % 10# print(get_digit(12345, 6)) 2、列表反轉,不用內置函數 def reverse_list(li):n len(li)for i in range(n // 2):li[i], li[n-i-1] li[n-i-1], …

在python中os_在Python中使用os.execvp

我有一個關于在 Python中使用os.execvp的問題.我有以下用于創建參數列表的代碼: args [ "java" , classpath , "-Djava.library.path" lib_path() , ea , "-Xmx1000m" , "-server" , "code_swarm" , params ] …

WEBGL學習【四】模型視圖矩陣

<html lang"zh-CN"><!--服務器運行地址&#xff1a;http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html--> <head><title>NeHes WebGL</title><meta charset"UTF-8"/><!--引入需要的庫文件--><scr…

使用Jmeter對mysql進行性能測試入門

使用Jmeter對mysql進行性能測試入門 第一步&#xff1a;測試環境準備&#xff1a; 1&#xff09;、mysql> select version(); ----------- | version() | ----------- | 5.5.13 | ----------- ms數據庫數據&#xff1a; mysql> select count(*) from account; ----------…

算法基礎之數據結構

whats the 數據結構 數據結構是指相互之間存在著一種或多種關系的數據元素的集合和該集合中數據元素之間的關系組成。 簡單來說&#xff0c;數據結構就是設計數據以何種方式組織并存儲在計算機中。 比如&#xff1a;列表、集合與字典等都是一種數據結構。 通常情況下&#xff…