① 如何jvm監控linux伺服器
如何配置visualvm監控
visualvm支持在Linux和windows上啟用圖形界面監控jvm的資源,但是如何可以使我們在windows上監控到遠程linux伺服器資源,這還需要做一些配置,此文是在原文基礎上做了更改的,希望對大家能有所幫助。
(1)首先要修改JDK中JMX服務的配置文件,以獲得相應的許可權:
進入$java_HOME所在的根目錄的/jre/lib/management子目錄下,
a. 將jmxremote.password.template文件復制為jmxremote.password
b. 調整jmxremote.access和jmxremote.password的許可權為只讀寫,可以使用如下命令
chmod 600 jmxremote.access jmxremote.password
c. 打開jmxremote.password文件,去掉
# monitorRole QED
# controlRole R&D
這兩行前面的注釋符號
(2)修改env.sh
打開env.sh文件,並在JVM的啟動配置中添加如下信息:
JAVA_OPTS="-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.20.150.218 其他配置」
這幾個配置的說明如下:
-Dcom.sun.management.jmxremote.port:這個是配置遠程connection的埠號的,要確定這個埠沒有被佔用
-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false:這兩個是固定配置,是JMX的遠程服務許可權的
-Djava.rmi.server.hostname:這個是配置server的IP的,要使用server的IP最好在機器上先用hostname –i看一下IP是不是機器本身的IP,如果是127.0.0.1的話要改一下,否則遠程的時候連不上,目前我們的server上我已經都改好了
(3)Windows客戶端配置
JDK 1.6版本自帶visualvm,只需要進到bin目錄下啟動即可
啟動後頁面比較簡潔,配置也很簡單:
a. 點擊左側菜單的add Remote host,輸入server的IP,然後再advanced settings里配置埠(注意這個埠要和server上的埠一致)
b. 右擊剛才配置的IP,選擇JMX connection方式,再次輸入埠,就可以監視到JVM資源了
② 如何用jmx監控tomcat 伺服器
使用jmx監控tomcat
1、在tomcat啟動過程中,開啟相應的參數配置:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
其中:com.sun.management.jmxremote.port 是jmx埠 這個很重要 在使用jconsole連接tomcat jmx時候使用。
2、啟動tomcat並使用jconsole來連接tomcat jmx介面
連接界面如下:
連接進去以後,在MBean一欄便是jmx介面。
關於jmx相關介面信息如下(主要包括java jmx介面和tomcat jmx介面兩個部分)
③ 在新建虛擬機時出現問題
JConsole
JConsole 圖形用戶界面是一種符合 Java 管理擴展(JMX)規范的監視工具。JConsole 使用 Java 虛擬機 (Java VM) 的廣泛檢測來提供有關在 Java 平台上運行的應用程序的性能和資源消耗的信息。
使用方法 本地
使用jconsole命令:監視本地運行的所有 Java 應用程序,JConsole 可以連接到這些應用程序。
使用jconsole PID命令:監視指定PID的Java應用程序。
使用jsconsole hostName:portNum命令:hostName是運行應用程序的系統的名稱,portNum是您在啟動Java VM時啟用 JMX 代理時指定的埠號。
使用service:jmx::命令:使用 JMX 服務 URL 進行連接。
內容分析
將 JConsole 連接到應用程序後,JConsole 由六個選項卡組成。
概述:顯示有關 Java VM 和受監視值的概述信息。
內存:顯示有關內存使用的信息。
線程:顯示有關線程使用的信息。
類:顯示有關類載入的信息。
VM:顯示有關 Java VM 的信息。
MBeans:顯示有關 MBeans 的信息。
顯示有關 CPU 使用情況、內存使用情況、線程計數和在Java VM中載入的類的圖形監視信息。
提供執行GC的操作,可以隨時點擊按鈕進行垃圾回收
伊甸園空間(堆):最初為大多數對象分配內存的池。
倖存者空間(堆):包含在伊甸園空間垃圾回收中倖存下來的物體的池。
終身代(堆):包含在倖存者空間中存在一段時間的對象的池。
永久生成(非堆):包含虛擬機本身的所有反射數據的池,如類和方法對象。使用類數據共享的 Java VM,這一代分為只讀和讀寫區域。
代碼緩存(非堆):HotSpotJava VM 還包括一個代碼緩存,其中包含用於編譯和存儲本機代碼的內存。
Java VM管理兩種類型的內存:堆內存和非堆內存,這兩種內存都是在 Java VM 啟動時創建的。
堆內存是Java VM為所有類實例和數組分配內存的運行時數據區域。堆的大小可能是固定的或可變的。垃圾回收器是一個自動內存管理系統,用於回收對象的堆內存。
非堆內存包括所有線程之間共享的方法區域和Java VM的內部處理或優化所需的內存。它存儲每類結構,如運行時常量池、欄位和方法數據,以及方法和構造函數的代碼。方法區域在邏輯上是堆的一部分,但是,根據實現,Java VM 可能不會對它進行垃圾回收或壓縮。與堆內存一樣,方法區域可能為固定大小或可變大小。方法區域的內存不需要連續。
內存池和內存管理器是Java VM內存系統的關鍵方面。
內存池表示Java VM管理的內存區域。Java VM至少有一個內存池,它可能會在執行期間創建或刪除內存池。內存池可以屬於堆內存或非堆內存。
內存管理器管理一個或多個內存池。垃圾回收器是一種內存管理器,負責回收不可到達的對象使用的內存。Java VM可能具有一個或多個內存管理器。它可以在執行期間添加或刪除內存管理器。內存池可以由多個內存管理器管理。
垃圾回收 (GC) 是Java VM釋放不再引用的對象佔用的內存的方式。通常認為具有活動引用為"活動"且未引用(或無法訪問)對象的對象為"已死"。垃圾回收是釋放死對象使用的內存的過程。GC 使用的演算法和參數對性能有顯著影響。
Java hotspot VM垃圾回收器使用代數 GC。生成 GC 利用大多數程序符合以下概括的觀察。
它們創建許多壽命較短的對象,例如迭代器和局部變數。
它們創建一些壽命很長的對象,例如高級持久對象。
提供有關線程使用的信息。
查找監視器死鎖線程:檢測對象監視器鎖上是否有任何線程死鎖。此操作返回死鎖線程指示的數組。
getThreadInfo:返回線程信息。這包括線程當前被阻止的名稱、堆棧跟蹤和監視器鎖(如果有)以及持有該鎖的線程以及線程爭用統計信息。
獲取ThreadCpu時間:返回給定線程消耗的 CPU 時間
顯示有關類載入的信息。
提供有關Java VM的信息。
以通用方式顯示有關在平台 MBean 伺服器注冊的所有 MBeans 的信息。MBeans 選項卡允許您訪問平台 MXBean 檢測的完整集,包括在其他選項卡中不可見的儀器。此外,您還可以使用 MBeans 選項卡監視和管理應用程序的 MBeans。
列出目標系統上已檢測的 Java 虛擬機 (JVM)。
監視 Java 虛擬機 (JVM) 統計信息。
對Java應用程序的資源和性能進行實時的命令行的監控,包括了對Heap size和垃圾回收狀況的監控。
命令格式
jstat [-option] [PID]
option參數
class:顯示有關類載入器行為的統計信息。
compiler:顯示有關Java HotSpot VM實時編譯器行為的統計信息。
gc:顯示有關垃圾回收堆行為的統計信息。
gccapacity:顯示有關幾代人容量及其相應空間的統計信息。
gccause:顯示有關垃圾回收統計信息(與 相同)的摘要,以及最後和當前(如果適用)垃圾回收事件的原因。-gcutil
gcnew:顯示新一代行為的統計信息。
gcnewcapacity:顯示有關新一代大小及其相應空間的統計信息。
gcold:顯示有關舊一代和元空間統計信息行為的統計信息。
gcoldcapacity:顯示有關舊一代大小的統計信息。
gcmetacapacity:顯示有關元空間大小的統計信息。
gcutil:顯示有關垃圾回收統計信息的摘要。
printcompilation:顯示 Java 熱點 VM 編譯方法統計信息。
1.jstat –class: 顯示載入class的數量,及所佔空間等信息。
2.jstat -compiler顯示VM實時編譯的數量等信息。
3.jstat -gc: 可以顯示gc的信息,查看gc的次數,及時間。
4.jstat -gccapacity:可以顯示,VM內存中三代(young,old,perm)對象的使用和佔用大小
5.jstat -gcutil:統計gc信息
6.jstat -gcnew:年輕代對象的信息。
7.jstat -gcnewcapacity: 年輕代對象的信息及其佔用量。
8.jstat -gcold:old代對象的信息。
9.jstat -gcoldcapacity: old代對象的信息及其佔用量。
10.jstat -gcpermcapacity: perm對象的信息及其佔用量。
11.jstat -printcompilation:當前VM執行的信息。
監視 Java 虛擬機 (JVM),並使遠程監視工具能夠連接到 JVM
命令格式
jstatd -[option]
option
-nr當找不到現有的RMI注冊表時,不嘗試使用jstatd進程創建一個內部的RMI注冊表。
-p port在指定的埠查找RMI注冊表。如果沒有找到,並且沒有指定-nr選項,則在該埠自行創建一個內部的RMI注冊表。
-n rminameRMI注冊表中綁定的RMI遠程對象的名稱。默認的名稱為JStatRemoteHost。如果多個jstatd伺服器在同一主機上運行,你可以通過指定該選項來讓每個伺服器導出的RMI對象具有唯一的名稱。不管如何,這樣做需要將唯一的伺服器名稱包含進監控客戶端的hostid和vmid字元串中。
-Joption將選項參數傳遞給被javac調用的java啟動程序。例如,-J-Xms48m設置啟動內存為48 MB。使用-J將選項參數傳遞給執行Java應用程序的底層虛擬機,這是一種常見慣例。
使用方法
1.在jdk的bin目錄下創建文件jstatd.all.policy
2.寫入下面的安全配置
grant codebase "file:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64/lib/tools.jar" {
permission java.security.AllPermission;
#此處寫絕對路徑,主要是防止路徑錯誤問題,排查問題,應該寫成相對路徑
3.啟動jstatd
./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=x.x.x.x &
4.使用jvisualvm工具遠程連接,進行監控
jvisualvm
VisualVM,能夠監控線程,內存情況,查看方法的CPU時間和內存中的對 象,已被GC的對象,反向查看分配的堆棧(如100個String對象分別由哪幾個對象分配出來的).
同時他還提供很多插件可以自己安裝,是一款不錯的監控分析工具。
故障排除工具 JInfo
可以用來查看正在運行的 java 應用程序的擴展參數,包括Java System屬性和JVM命令行參數;也可以動態的修改正在運行的 JVM 一些參數。當系統崩潰時,jinfo可以從core文件裡面知道崩潰的Java應用程序的配置信息
命令格式
參數說明
pid對應jvm的進程id
executable core產生core mp文件
[server-id@]remote server IP or hostname遠程的ip或者hostname,server-id標記服務的唯一性id
option
no option輸出全部的參數和系統屬性
-flag name輸出對應名稱的參數
-flag [+|-]name開啟或者關閉對應名稱的參數
-flag name=value設定對應名稱的參數
-flags輸出全部的參數
-sysprops輸出系統屬性
Javacore 概述
Javacore,也可以稱為「threadmp」或是「javamp」,它是 Java 提供的一種診斷特性,能夠提供一份可讀的當前運行的 JVM 中線程使用情況的快照。即在某個特定時刻,JVM 中有哪些線程在運行,每個線程執行到哪一個類,哪一個方法。應用程序如果出現不可恢復的錯誤或是內存泄露,就會自動觸發 Javacore 的生成。
使用方法
1.jinfo pid:輸出當前 jvm 進程的全部參數和系統屬性
2.jinfo -flag name pid:輸出對應名稱的參數使用該命令,可以查看指定的 jvm 參數的值。如:查看當前 jvm 進程是否開啟列印 GC 日誌。
3.jinfo -flag [+|-]name pid:開啟或者關閉對應名稱的參數
使用 jinfo 可以在不重啟虛擬機的情況下,可以動態的修改 jvm 的參數。尤其在線上的環境特別有用。
4.jinfo -flag name=value pid:修改指定參數的值。
5.jinfo -flags pid:輸出全部的參數
6.jinfo -sysprops pid:輸出當前 jvm 進行的全部的系統屬性
jhat
主要是用來分析java堆的命令,可以將堆中的對象以html的形式顯示出來,包括對象的數量,大小等等,並支持對象查詢語言。
1.使用jmap命令導出堆文件jmap -mp:live,file=a.log pid
也可以使用下面方式導出堆文件
1、使用jconsole選項通過HotSpotDiagnosticMXBean從運行時獲得堆轉儲(生成mp文件)、
2、虛擬機啟動時如果指定了-XX:+HeapDumpOnOutOfMemoryError選項, 則在拋出OutOfMemoryError時, 會自動執行堆轉儲。
3、使用hprof命令
2.使用jhat分析堆文件jhat -J-Xmx512M a1.log
3.查看分析的html頁面
http://ip:7000/jhat中的OQL(對象查詢語言)
如果需要根據某些條件來過濾或查詢堆的對象,這是可能的,可以在jhat的html頁面中執行OQL,來查詢符合條件的對象
基本語法:
select
[from [instanceof] ]
[where ]
解釋:
(1)class name是java類的完全限定名,如:java.lang.String,java.util.ArrayList, C是char數組,java.io.File是java.io.File[]
(2)類的完全限定名不足以唯一的辨識一個類,因為不同的ClassLoader載入的相同的類,它們在jvm中是不同類型的
(3)instanceof表示也查詢某一個類的子類,如果不明確instanceof,則只精確查詢class name指定的類
(4)from和where子句都是可選的
(5)java域表示:obj.field_name;java數組表示:array[index]
舉例:
(1)查詢長度大於100的字元串
select s from java.lang.String s where s.count > 100
(2)查詢長度大於256的數組
select a from [I a where a.length > 256
(3)顯示匹配某一正則表達式的字元串
select a.value.toString() from java.lang.String s where /java/(s.value.toString())
(4)顯示所有文件對象的文件路徑
select file.path.value.toString() from java.io.File file
(5)顯示所有ClassLoader的類名
select classof(cl).name from instanceof java.lang.ClassLoader cl
(6)通過引用查詢對象
select o from instanceof 0xd404d404 o
built-in對象 -- heap
(1)heap.findClass(class name) -- 找到類
select heap.findClass("java.lang.String").superclass
(2)heap.findObject(object id) -- 找到對象
select heap.findObject("0xd404d404")
(3)heap.classes -- 所有類的枚舉
select heap.classes
(4)heap.objects -- 所有對象的枚舉
select heap.objects("java.lang.String")
(5)heap.finalizables -- 等待垃圾收集的java對象的枚舉
(6)heap.livepaths -- 某一對象存活路徑
select heaplivepaths(s) from java.lang.String s
(7)heap.roots -- 堆根集的枚舉
辨識對象的函數
(1)classof(class name) -- 返回java對象的類對象
select classof(cl).name from instanceof java.lang.ClassLoader cl
(2)identical(object1,object2) -- 返回是否兩個對象是同一個實例
select identical(heap.findClass("java.lang.String").name, heap.findClass("java.lang.String").name)
(3)objectid(object) -- 返回對象的id
select objectid(s) from java.lang.String s
(4)reachables -- 返回可從對象可到達的對象
select reachables(p) from java.util.Properties p -- 查詢從Properties對象可到達的對象
select reachables(u, "java.net.URL.handler") from java.net.URL u -- 查詢從URL對象可到達的對象,但不包括從URL.handler可到達的對象
(5)referrers(object) -- 返回引用某一對象的對象
select referrers(s) from java.lang.String s where s.count > 100
(6)referees(object) -- 返回某一對象引用的對象
select referees(s) from java.lang.String s where s.count > 100
(7)refers(object1,object2) -- 返回是否第一個對象引用第二個對象
select refers(heap.findObject("0xd4d4d4d4"),heap.findObject("0xe4e4e4e4"))
(8)root(object) -- 返回是否對象是根集的成員
select root(heap.findObject("0xd4d4d4d4"))
(9)sizeof(object) -- 返回對象的大小
select sizeof(o) from [I o
(10)toHtml(object) -- 返回對象的html格式
select "+ toHtml(o) + "" from java.lang.Object o
(11)選擇多值
select {name:t.name?t.name.toString():"null",thread:t} from instanceof java.lang.Thread t
數組、迭代器等函數
(1)concat(enumeration1,enumeration2) -- 將數組或枚舉進行連接
select concat(referrers(p),referrers(p)) from java.util.Properties p
(2)contains(array, expression) -- 數組中元素是否滿足某表達式
select p from java.util.Properties where contains(referres(p), "classof(it).name == 'java.lang.Class'")
返回由java.lang.Class引用的java.util.Properties對象
built-in變數
it -- 當前的迭代元素
index -- 當前迭代元素的索引
array -- 被迭代的數組
(3)count(array, expression) -- 滿足某一條件的元素的數量
select count(heap.classes(), "/java.io./(it.name)")
(4)filter(array, expression) -- 過濾出滿足某一條件的元素
select filter(heap.classes(), "/java.io./(it.name)")
(5)length(array) -- 返回數組長度
select length(heap.classes())
(6)map(array,expression) -- 根據表達式對數組中的元素進行轉換映射
select map(heap.classes(),"index + '-->' + toHtml(it)")
(7)max(array,expression) -- 最大值, min(array,expression)
select max(heap.objects("java.lang.String"),"lhs.count>rhs.count")
built-in變數
lhs -- 左邊元素
rhs -- 右邊元素
(8)sort(array,expression) -- 排序
select sort(heap.objects('[C'),'sizeof(lhs)-sizeof(rhs)')
(9)sum(array,expression) -- 求和
select sum(heap.objects('[C'),'sizeof(it)')
(10)toArray(array) -- 返回數組
(11)unique(array) -- 唯一化數組
jmap
列印進程、核心文件或遠程調試伺服器的共享對象內存映射或堆內存詳細信息。
jmap [option]
(to connect to running process) 連接到正在運行的進程
jmap [option]
(to connect to a core file) 連接到核心文件
jmap [option] [server_id@]
(to connect to remote debug server) 連接到遠程調試服務
option
pid:目標進程的PID,進程編號,可以採用ps -ef | grep java查看java進程的PID;
executable:產生core mp的java可執行程序;
core:將被列印信息的core mp文件;
remote-hostname-or-IP:遠程debug服務的主機名或ip;
server-id:唯一id,假如一台主機上多個遠程debug服務;
使用方法
jmap -mp:[live,]format=b,file= PID:使用hprof二進制形式,輸出jvm的heap內容到文件
jmap -finalizerinfo PID:列印正等候回收的對象的信息
jmap -heap PID:列印heap的概要信息,GC使用的演算法,heap(堆)的配置及JVM堆內存的使用情況。
jmap -histo:live PID:列印每個class的實例數目,內存佔用,類全名信息。VM的內部類名字開頭會加上前綴」*」. 如果live子參數加上後,只統計活的對象數量.
jmap -permstat PID:列印classload和jvm heap長久層的信息. 包含每個classloader的名字、活潑性、地址、父classloader和載入的class數量。另外,內部String的數量和佔用內存數也會列印出來。
-F強迫.在pid沒有相應的時候使用-mp或者-histo參數。在這個模式下,live子參數無效。
-h | -help列印輔助信息
-J傳遞參數給jmap啟動的jvm.
jstack命令主要用於調試java程序運行過程中的線程堆棧信息,可以用於檢測死鎖,進程耗用cpu過高報警問題的排查。jstack命令會列印出所有的線程,包括用戶自己啟動的線程和jvm後台線程。
命令格式
jstack -[option] pid
option
-F強制mp線程堆棧信息. 用於進程hung住,jstack命令沒有響應的情況
-m同時列印java和本地(native)線程棧信息,m是mixed mode的簡寫
-l列印鎖的額外信
公眾號「Java精選」所發表內容註明來源的,版權歸原出處所有(無法查證版權的或者未註明出處的均來自網路,系轉載,轉載的目的在於傳遞更多信息,版權屬於原作者。如有侵權,請聯系,筆者會第一時間刪除處理!
最近有很多人問,有沒有讀者交流群!加入方式很簡單,公眾號Java精選,回復「加群」,即可入群!
(微信小程序):3000+道面試題,包含Java基礎、並發、JVM、線程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架構設計等,在線隨時刷題!
------ 特別推薦 ------
特別推薦:專注分享最前沿的技術與資訊,為彎道超車做好准備及各種開源項目與高效率軟體的公眾號,「大咖筆記」,專注挖掘好東西,非常值得大家關注。點擊下方公眾號卡片關注。
文章有幫助的話,在看,轉發吧!