jps、jmap、jstack已經Out了,使用jcmd進行JVM效能和記憶體跟蹤微調 -DZone Java
當您的應用程式在真實環境中執行時,您開始遇到在本地或開發環境中未發現的問題。
您如何與應用程式進行互動以查詢應用程式的執行方式並找到問題的根源?JVM的優勢之一是可用於診斷的工具數量眾多。
如果監視和應用程式日誌提供的資訊不夠,我們必須進入伺服器並使用這種型別的實用程式。
其中一些被視為實驗性的工具(jps,jmap,jstack ...)正在收斂到jcmd命令中。
jcmd是隨JDK一起分發的只有幾千位元組的實用程式。它只是JVM的前端/客戶端,所有邏輯都駐留在JVM中。如果您使用不包含jcmd可執行檔案的發行版或docker映像,並將其新增到路徑中,則它將不起作用。您需要使用jcmd模組生成JVM 。
這裡可以學習如何使用jcmd診斷問題:獲取堆疊跟蹤,記憶體直方圖,堆轉儲,GC日誌等。
獲取pid
每個程式都有一個關聯的程式ID,稱為pid。要獲得與我們的應用程式關聯的pid,可以使用jcmd本身,它將列出所有適用的Java程式。
$JAVA_HOME/bin/jcmd 12385 org.apache.catalina.startup.Bootstrap start 3019 sun.tools.jcmd.JCmd |
我們的應用是tomcat的12385
JCMD命令列表
鍵入:
jcmd 12385 help |
- 獲得虛擬機器版本:
jcmd 12385 VM.version 12385: Java HotSpot(TM) Server VM version 25.171-b11 JDK 8.0_171 |
- 虛擬機器JVM引數
jcmd 12385 VM.flags 12385: -XX:CICompilerCount=2 -XX:CMSInitiatingOccupancyFraction=90 -XX:+CMSParallelRemarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -XX:InitialHeapSize=1572864000 -XX:+ManagementServer -XX:MaxGCPauseMillis=50 -XX:MaxHeapSize=1572864000 -XX:MaxNewSize=134217728 -XX:MaxTenuringThreshold=6 -XX:MinHeapDeltaBytes=131072 -XX:NewSize=134217728 -XX:OldPLABSize=16 -XX:OldSize=1438646272 -XX:+ScavengeBeforeFullGC -XX:+UseAdaptiveGCBoundary -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseConcMarkSweepGC -XX:+UseParNewGC |
其他命令,例如VM.system_properties,VM.command_line,VM.uptime,VM.dynlibs,還提供了有關所使用的各種其他屬性的其他基本和有用的詳細資訊。
- 執行緒列印
該命令用於獲取執行緒轉儲,即它將列印當前正在執行的所有執行緒的堆疊跟蹤。
jcmd 12385 Thread.print |
- GC.class_histogram
該命令將提供有關堆使用情況的重要資訊,並列出所有類(外部類或特定於應用程式的類)以及許多例項,並按堆使用情況對它們的堆使用進行排序。由於此列表很長,因此可以使用grep命令來查詢其已知的類以驗證詳細資訊,或者可以將此命令的輸出路由到檔案輸出。以下是JiveJdon執行情況:
num instances bytes class name ---------------------------------------------- 1: 851817 171944304 [C 2: 5157 33565504 [B 3: 81230 17192520 [Ljava.lang.Object; 4: 849365 13589840 java.lang.String 5: 265701 8502432 java.lang.ref.Finalizer 6: 504856 8077696 java.lang.Long 7: 222058 5329392 java.util.ArrayList 8: 58818 5175984 com.jdon.jivejdon.domain.model.ForumMessageReply 9: 114716 4588640 com.google.common.cache.LocalCache$StrongAccessEntry 10: 79245 1901880 com.jdon.jivejdon.domain.model.message.MessageVO 11: 114720 1835520 com.google.common.cache.LocalCache$StrongValueReference 12: 114716 1835456 com.jdon.cache.CacheableWrapper 13: 20427 1634160 com.jdon.jivejdon.domain.model.ForumMessage |
- GC.heap_dump
如果要立即獲取jvm堆轉儲,則可以執行此命令。
jcmp 12385 GC.heap_dump 檔名 |
- JFR命令選項
如果要分析其應用程式的效能問題,那麼JFR(即Java Flight Recorder)是一種提供資訊的實用工具。儘管JFR是一項商業功能,但人們可以在其本地計算機上免費使用它。
jcmd命令可以提供相關的JFR檔案以進行動態分析。預設情況下,JFR功能處於禁用狀態,要啟用這些功能,需要使用JFR.start
啟用JFR功能後,開始JFR錄製。就我而言,我要求在延遲10秒後記錄30秒。可以根據用途進行配置。也可以使用 JFR.check 命令檢查記錄的狀態。
- VM.native_memory(本機記憶體跟蹤)
這是最好的命令之一,可以提供有關堆和非堆 記憶體的許多有用的詳細資訊。這可用於調整記憶體使用情況並檢測任何記憶體洩漏。
眾所周知,JVM記憶體的使用取決於許多記憶體區域,大致分為堆和非堆記憶體。要獲取完整的JVM記憶體使用情況的詳細資訊,請使用此實用程式。如果要建立分散式應用程式,則這對於定義應用程式容器的大小很有用,如果正確調整,則可以節省成本。
要使用此功能,我必須使用其他引數重新啟動應用程式,即-XX:NativeMemoryTracking = summary 或 -XX:NativeMemoryTracking = detail。
結果解釋:
Java Heap記憶體外,Thread項指定執行緒正在使用的記憶體,Class項還指定捕獲的用於儲存類後設資料的記憶體,Code項提供用於儲存JIT生成的程式碼的記憶體,Compiler項本身具有一定的空間使用率,類似GC佔用空間。所有這些都屬於本機記憶體使用情況。reserved項可以粗略估計您的應用程式所需的記憶體,但是各種VM引數仍然可以控制事情,這主要是預設記憶體使用情況。
例如:
Java Heap (reserved=524288KB, committed=524288KB) (mmap: reserved=524288KB, committed=524288KB) |
我們預定reserved了堆記憶體即Xms = 512m,相當於524288KB,因此JVM確認的記憶體與Xms相同。同樣,Xmx對映到預定的記憶體。
- 記憶體洩漏分析
VM.native_memory命令提供當前記憶體使用情況的快照。要分析記憶體洩漏,應在使用命令啟動應用程式後將記憶體統計資訊作為基準:
jcmd #pid VM.native_memory baseline |
然後,可以使用summary.diff觀察更改,確切地使用記憶體。隨著GC的執行,您會發現記憶體增加和減少。但是,如果僅增加記憶體使用量,則可能是記憶體洩漏問題。確定洩漏區域,例如堆,執行緒,程式碼,類等。如果您的應用程式需要更多記憶體,請相應地調整相應的VM引數。
如果記憶體洩漏在堆中,請進行堆轉儲(如前所述),或者如果執行緒數在增加,請使用執行緒池。如果任何執行緒導致OOM,可以調整Xss。
thread (reserved=11895KB +529KB, committed=11895KB +529KB) (thread #20 +2) (stack: reserved=11812KB +520KB, committed=11812KB +520KB) (malloc=61KB +7KB #101 +10) (arena=22KB +2 #35 +4) |
“ stack ”顯示執行緒堆疊記憶體,這可能與執行應用程式時使用Xss配置的內容不匹配。由於某些jvm系統執行緒會根據使用情況分配堆疊記憶體,因此使用者無法使用Xss覆蓋堆疊記憶體。
我們將執行緒堆疊大小指定為Xss = 256k,這裡共有18 + 2 = 20個執行緒。這兩個額外的執行緒是處理請求的特定於應用程式的執行緒,因此2 *(Xss = 256k)〜520k。
相關文章
- 使用async-profiler進行JVM記憶體效能微調的指南 | BaeldungJVM記憶體
- Java命令列監控工具(jmap,jstack,jstat,jinfo,jps)Java命令列JS
- JVM中的本機記憶體跟蹤JVM記憶體
- (轉)JVM調優常用命令(jstat、jmap、jstack)JVMJS
- jstack和jmap1JS
- JVM效能調優,記憶體分析工具JVM記憶體
- JDK幾個很實用的工具 jps、jinfo、jstat、jstack、jmap、jconsoleJDKJS
- JVM監控工具:jps、jstat、jinfo、jmap、jhat、jJVMJS
- 效能調優(cpu/IO/JVM記憶體分析)JVM記憶體
- 如何在Java 9以上的JVM中微調G1垃圾回收? - DZone效能JavaJVM
- JVM記憶體結構、Java記憶體模型和Java物件模型JVM記憶體Java模型物件
- 使用mtrace追蹤JVM堆外記憶體洩露JVM記憶體洩露
- 淺談JVM記憶體結構 和 Java記憶體模型 和 Java物件模型JVM記憶體Java模型物件
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- Java命令列監控工具(jmap,jstack,jstat,jinfoJava命令列JS
- JVM記憶體JAVA_OPTSJVM記憶體Java
- Java面試題中高階進階(JVM篇Java記憶體)Java面試題JVM記憶體
- 只知道ajax?你已經out了
- git列出所有已經跟蹤檔案Git
- SQLServer進行SQL跟蹤SQLServer
- 效能調優命令之jstackJS
- Java記憶體管理 -JVM 垃圾回收Java記憶體JVM
- Spring Cloud Sleuth 和 Zipkin 進行分散式跟蹤使用指南SpringCloud分散式
- [效能]【JVM】關於JVM記憶體的N個問題JVM記憶體
- 圖解JVM記憶體模型及JAVA程式執行原理圖解JVM記憶體模型Java
- 【JVM】堆體系結構及其記憶體調優JVM記憶體
- JVM記憶體管理和垃圾回收JVM記憶體
- 使用OpenCV進行ROS 2的循線跟蹤OpenCVROS
- 使用ErrorStack進行錯誤跟蹤及診斷Error
- 使用Redis和Java進行資料庫快取 - DZone資料庫RedisJava資料庫快取
- JVM的藝術—JAVA記憶體模型JVMJava記憶體模型
- jvm-44-jvm 記憶體效能分析工具 Eclipse Memory Analyzer Tool (MAT) / 記憶體分析器 (MAT)JVM記憶體Eclipse
- JVM(2)-Java記憶體區域與記憶體溢位異常JVMJava記憶體溢位
- 深入理解Java的堆記憶體和執行緒記憶體Java記憶體執行緒
- JAVA-大白話探索JVM-執行時記憶體(三)JavaJVM記憶體
- NIO的JVM記憶體和機器記憶體的選擇JVM記憶體
- 利用errorstack事件進行錯誤跟蹤和診斷Error事件
- JVM-概述和記憶體區域JVM記憶體