1. 程式人生 > 實用技巧 >Java記憶體佔用排查的方法

Java記憶體佔用排查的方法

使用htop檢視程序的記憶體佔用

$ htop

相關名詞:

VIRTvirtual memory usage 虛擬記憶體

  • 程序“需要的”虛擬記憶體大小,包括程序使用的庫、程式碼、資料等
  • 假如程序申請100m的記憶體,但實際只使用了10m,那麼它會增長100m,而不是實際的使用量

RESresident memory usage 常駐記憶體

  • 程序當前使用的記憶體大小,但不包括swap out
  • 包含其他程序的共享
  • 如果申請100m的記憶體,實際使用10m,它只增長10m,與VIRT相反
  • 關於庫佔用記憶體的情況,它只統計載入的庫檔案所佔記憶體大小

SHRshared memory 共享記憶體

  • 除了自身程序的共享記憶體,也包括其他程序的共享記憶體
  • 雖然程序只使用了幾個共享庫的函式,但它包含了整個共享庫的大小
  • 計算某個程序所佔的實體記憶體大小公式:RES – SHR
  • swap out後,它將會降下來

使用pmap檢視程序的記憶體分佈

先使用htop找到java程序的程序id,然後:

pmap -x 30420

上面的命令的輸出結果沒法進行排序找出較大的記憶體塊,建議匯出成檔案,下載到自己本機分析。我自己的做法是在自己本機使用IDEA開啟,然後利用多行編輯功能在每一列新增英文逗號“,”,因為這樣能都對RSS(Resident Set Size)列排序,具體操作如下:

RSS 是常駐記憶體集(Resident Set Size),表示該程序分配的記憶體大小

匯出:

# 在伺服器上匯出
pmap -x 30420 > pmap30420.csv

# 利用lszrz下載
sz -be pmap30420.csv

然後vscode(不要用IDEA,很卡。行數多的時候vscode沒那麼卡)開啟,利用多行編輯(快捷鍵alt + shift + up/down)加英文逗號:

然後就可以用Excel開啟,對第三列RSS倒序排序找出可疑的(佔用多的)是哪些記憶體塊:

JVM開啟 Native Memory Tracking 檢視JVM記憶體

注意:NMT是用來看Java程序中JVM部分的記憶體情況,並非整個Java程序的記憶體情況

java -XX:NativeMemoryTracking=[detail|summary]

# 例如:
java -Xms500M -Xmx1500M -XX:NativeMemoryTracking=detail -jar ewulian-server.jar

然後使用jcmd

# 加detail是看詳情
jcmd PID VM.native_memory [detail]

例如:

$ jcmd 30420 VM.native_memory > jcmd30420-summary.txt
$ cat jcmd30420-summary.txt
30420:

Native Memory Tracking:

Total: reserved=3201582KB, committed=991846KB
-                 Java Heap (reserved=1536000KB, committed=565760KB)
                            (mmap: reserved=1536000KB, committed=565760KB) 
 
-                     Class (reserved=1141993KB, committed=104385KB)
                            (classes #15022)
                            (malloc=7401KB #29512) 
                            (mmap: reserved=1134592KB, committed=96984KB) 
 
-                    Thread (reserved=77490KB, committed=77490KB)
                            (thread #76)
                            (stack: reserved=77060KB, committed=77060KB)
                            (malloc=246KB #381) 
                            (arena=184KB #147)
 
-                      Code (reserved=260241KB, committed=61473KB)
                            (malloc=10641KB #14504) 
                            (mmap: reserved=249600KB, committed=50832KB) 
 
-                        GC (reserved=61908KB, committed=58788KB)
                            (malloc=5784KB #490) 
                            (mmap: reserved=56124KB, committed=53004KB) 
 
-                  Compiler (reserved=365KB, committed=365KB)
                            (malloc=235KB #1216) 
                            (arena=131KB #6)
 
-                  Internal (reserved=98440KB, committed=98440KB)
                            (malloc=98408KB #21205) 
                            (mmap: reserved=32KB, committed=32KB) 
 
-                    Symbol (reserved=20667KB, committed=20667KB)
                            (malloc=17590KB #178837) 
                            (arena=3077KB #1)
 
-    Native Memory Tracking (reserved=4353KB, committed=4353KB)
                            (malloc=412KB #5868) 
                            (tracking overhead=3942KB)
 
-               Arena Chunk (reserved=125KB, committed=125KB)
                            (malloc=125KB)