JDK本地內存追蹤NMT


通常情況下, JVM占用的內存不僅僅是-Xmx, -Xms等指定的大小, 因為JVM也是一個應用, 它需要額外的空間去完成它的工作, 除了堆外, JVM會分配內存的地方包括以下這些:

Metaspace: 元數據區, 存儲類, 及方法的元數據信息

Threads: 線程, 線程里的棧還是比較耗內存的, 在64位操作系統上, 默認棧的大小為1MB, 當然可以通過-Xss配置。

因為一般情況下線程的數量是沒有限制的, 因此可能會占用極其多的內存。

Code Cache: JVM通過JIT把字節碼轉換成機器指令, 然后把這些指令放到一個非堆區域Code Cache。

配置參數:

-XX:InitialCodeCacheSize: 初始大小

-XX:ReservedCodeCacheSize: 最大的空間大小

Garbage Collection: JVM的垃圾回收器需要使用到一個空間去完成它們的任務, 一些運行時的數據等等, 這個空間使用的更多的是本地內存(native memory)

符號表

String Pool: JVM復用字面量字符串的地方。

配置參數:

-XX:StringTableSize: 常量池大小

運行時常量池,JVM用來存儲編譯時的字面量或方法以及屬性地址(reference)。

Native Byte Buffers:

開發者可以直接使用本地內存, 如通過JNI的malloc或者NIO的ByteBuffers等。

 

Native Memory Tracking

那么怎么監控JVM使用到的這些內存嗎, 答案就是通過NMT(Native Memory Tracking), 但是使用它之前需要設置JVM的啟動參數:

-XX:NativeMemoryTracking, 可能的值為off, 關閉,也為默認值, summary, 顯示匯總信息, detail, 顯示詳細信息。

使用方法:

首先通過jps找到對應的Java程序的pid,然后使用如下命令:

jcmd <pid> VM.native_memory

 
我在本地運行jcmd后輸出結果為:

11132:

Native Memory Tracking:

Total: reserved=3517807KB, committed=548183KB
-                 Java Heap (reserved=2045952KB, committed=366080KB)
                            (mmap: reserved=2045952KB, committed=366080KB)

-                     Class (reserved=1089619KB, committed=46803KB)
                            (classes #8341)
                            (malloc=6227KB #11407)
                            (mmap: reserved=1083392KB, committed=40576KB)

-                    Thread (reserved=29820KB, committed=29820KB)
                            (thread #30)
                            (stack: reserved=29696KB, committed=29696KB)
                            (malloc=89KB #152)
                            (arena=35KB #59)

-                      Code (reserved=251467KB, committed=10383KB)
                            (malloc=1867KB #4673)
                            (mmap: reserved=249600KB, committed=8516KB)

-                        GC (reserved=80655KB, committed=74803KB)
                            (malloc=5775KB #218)
                            (mmap: reserved=74880KB, committed=69028KB)

-                  Compiler (reserved=149KB, committed=149KB)
                            (malloc=18KB #478)
                            (arena=131KB #3)

-                  Internal (reserved=6719KB, committed=6719KB)
                            (malloc=6655KB #11664)
                            (mmap: reserved=64KB, committed=64KB)

-                    Symbol (reserved=11371KB, committed=11371KB)
                            (malloc=9477KB #85817)
                            (arena=1894KB #1)

-    Native Memory Tracking (reserved=1880KB, committed=1880KB)
                            (malloc=72KB #1130)
                            (tracking overhead=1807KB)

-               Arena Chunk (reserved=176KB, committed=176KB)
                            (malloc=176KB)

11132是進程號pid

然后出現的很多reserved是指總共可用的內存大小, 而commited是指已經使用的內存大小。

 

追蹤本地內存的變化

NMT可以讓我們看到隨時間增長本地內存的變化。

首先需要設置一個對照的內存狀態:

jcmd <pid> VM.native_memory baseline

然后過一段時間如果需要查看變化狀態即:

jcmd <pid> VM.native_memory detail.diff

NMT通過+和-來顯示內存的變化:

Total: reserved=1771487KB +3373KB, committed=491491KB +6873KB
-             Java Heap (reserved=307200KB, committed=307200KB)
                        (mmap: reserved=307200KB, committed=307200KB)
  
-             Class (reserved=1084300KB +2103KB, committed=39356KB +2871KB)

Refer: https://www.baeldung.com/native-memory-tracking-in-jvm


免責聲明!

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



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