jvm堆外内存监控

java8给HotSpot VM引入了Native Memory Tracking (NMT)特性,可以用于追踪JVM的内部内存使用

开启

-XX:NativeMemoryTracking=summary

使用-XX:NativeMemoryTracking=summary可以用于开启NMT,其中该值默认为off,可以设置为summary或者detail来开启;开启的话,大概会增加5%-10%的性能消耗

查看

/ # jcmd 1 VM.native_memory summary
/ # jcmd 1 VM.native_memory summary scale=MB

使用jcmd pid VM.native_memory可以查看,后面可以加summary或者detail,如果是开启summary的,就只能使用summary;其中scale参数可以指定展示的单位,可以为KB或者MB或者GB

创建baseline

/ # jcmd 1 VM.native_memory baseline
Baseline succeeded

创建baseline之后可以用summary.diff来对比

查看diff

/ # jcmd 1 VM.native_memory summary.diff

使用summary.diff来查看跟baseline对比的统计信息

shutdown时输出

-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics

使用上述命令可以在jvm shutdown的时候输出整体的native memory统计

关闭

/ # jcmd 1 VM.native_memory shutdown
Native memory tracking has been turned off

使用jcmd pid VM.native_memory shutdown可以用于关闭NMT;注意使用jcmd关闭之后貌似没有对应jcmd命令来开启

实例

/ # jcmd 1 VM.native_memory summary scale=MB
Native Memory Tracking:

Total: reserved=12259645KB(保留内存), committed=11036265KB (提交内存)
堆内存使用情况,保留内存和提交内存和Xms、Xmx一致,都是8G。
-                 Java Heap (reserved=8388608KB, committed=8388608KB)
                            (mmap: reserved=8388608KB, committed=8388608KB)
用于存储类元数据信息使用到的原生内存,总共12045个类,整体实际使用了79M内存。
-                     Class (reserved=1119963KB, committed=79751KB)
                            (classes #12045)
                            (malloc=1755KB #29277)
                            (mmap: reserved=1118208KB, committed=77996KB)
总共2064个线程,提交内存是2.1G左右,一个线程1M,和设置Xss1m相符。
-                    Thread (reserved=2130294KB, committed=2130294KB)
                            (thread #2064)
                            (stack: reserved=2120764KB, committed=2120764KB)
                            (malloc=6824KB #10341)
                            (arena=2706KB #4127)
JIT的代码缓存,12045个类JIT编译后代码缓存整体使用79M内存。
-                      Code (reserved=263071KB, committed=79903KB)
                            (malloc=13471KB #15191)
                            (mmap: reserved=249600KB, committed=66432KB)
GC相关使用到的一些堆外内存,比如GC算法的处理锁会使用一些堆外空间。118M左右。
-                        GC (reserved=118432KB, committed=118432KB)
                            (malloc=93848KB #453)
                            (mmap: reserved=24584KB, committed=24584KB)
JAVA编译器自身操作使用到的一些堆外内存,很少。
-                  Compiler (reserved=975KB, committed=975KB)
                            (malloc=844KB #1074)
                            (arena=131KB #3)
Internal:memory used by the command line parser, JVMTI, properties等。
-                  Internal (reserved=117158KB, committed=117158KB)
                            (malloc=117126KB #44857)
                            (mmap: reserved=32KB, committed=32KB)
Symbol:保留字符串(Interned String)的引用与符号表引用放在这里,17M左右
-                    Symbol (reserved=17133KB, committed=17133KB)
                            (malloc=13354KB #145640)
                            (arena=3780KB #1)
NMT本身占用的堆外内存,4M左右
-    Native Memory Tracking (reserved=4402KB, committed=4402KB)
                            (malloc=396KB #5287)
                            (tracking overhead=4006KB)
不知道啥,用的很少。
-               Arena Chunk (reserved=272KB, committed=272KB)
                            (malloc=272KB)
其他未分类的堆外内存占用,100M左右。
-                   Unknown (reserved=99336KB, committed=99336KB)
                            (mmap: reserved=99336KB, committed=99336KB)
  • 可以看到整个memory主要包含了Java Heap、Class、Thread、Code、GC、Compiler、Internal、Other、Symbol、Native Memory Tracking、Arena Chunk这几部分;其中reserved表示应用可用的内存大小,committed表示应用正在使用的内存大小
  • Java Heap部分表示heap内存目前占用了463MB;Class部分表示已经加载的classes个数为8801,其metadata占用了50MB;Thread部分表示目前有225个线程,占用了27MB;Code部分表示JIT生成的或者缓存的instructions占用了17MB;GC部分表示目前已经占用了15MB的内存空间用于帮助GC;Code部分表示compiler生成code的时候占用了26MB;Internal部分表示命令行解析、JVMTI等占用了5MB;Other部分表示尚未归类的占用了2MB;Symbol部分表示诸如string table及constant pool等symbol占用了10MB;Native Memory Tracking部分表示该功能自身占用了5MB;Arena Chunk部分表示arena chunk占用了63MB
  • 一个arena表示使用malloc分配的一个memory chunk,这些chunks可以被其他subsystems做为临时内存使用,比如pre-thread的内存分配,它的内存释放是成bulk的
  • java8给HotSpot VM引入了Native Memory Tracking (NMT)特性,可以用于追踪JVM的内部内存使用
  • 使用-XX:NativeMemoryTracking=summary可以用于开启NMT,其中该值默认为off,可以设置summary、detail来开启;开启的话,大概会增加5%-10%的性能消耗;使用-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics可以在jvm shutdown的时候输出整体的native memory统计;其他的可以使用jcmd pid VM.native_memory相关命令进行查看、diff、shutdown等
  • 整个memory主要包含了Java Heap、Class、Thread、Code、GC、Compiler、Internal、Other、Symbol、Native Memory Tracking、Arena Chunk这几部分;其中reserved表示应用可用的内存大小,committed表示应用正在使用的内存大小

 

一个内存溢出问题的排查案例:

https://coldwalker.com/2018/12/troubleshooter_directbytebuffer_memory_issue/

容器内存限制后, 堆外内存不断增长导致容器被系统kill的案例

https://coderbee.net/index.php/jvm/20190913/1929

metaspace内存使用

https://www.javadoop.com/post/metaspace

直接内存分析:

https://juejin.im/entry/5bc33393f265da0a8a6ad13e

直接内存和internal内存占用的关系(可参考,不一定准确)

https://gist.github.com/prasanthj/48e7063cac88eb396bc9961fb3149b58

jvm中直接内存限制方式:,直接内存占用可以通过jconsole中的mbean查看到

-XX:MaxDirectMemorySize=1024M

你可能感兴趣的:(jvm)