Java內存占用排查的方法


htop:查進程的內存占用

$ htop

find-java-process-by-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)加英文逗號:

pmap-csv

然后就可以用Excel打開,對第三列RSS倒序排序找出可疑的(占用多的)是哪些內存塊:

pmap-excel

NMT:查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) 

jcmd還有其它功能,比如查看Java進程的堆直方圖

查看java進程的堆直方圖

$ jcmd 30420 GC.class_histogram | less

說明:

  • GC.class_histogram:輸出的僅包含活躍對象
  • [C:字符數組
  • [B:字節數組
  • [Ljava.lang.Object:Object數組

jcmd的其它功能可以通過help查看:

$ jcmd 30420 help
30420:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM