jcmd:向JVM发送诊断的命令,jvm未必会全部响应,有些需要在jvm开启相应功能才能响应。个人平时用的不是很多。

   SampleA: 添加        jcmd pid VM.native_memory detail 查看jvm内存分配情况(堆内内存、Code区域或者使用unsafe.allocateMemoryDirectByteBuffer申请的堆外内存),不包括底层c语言分配的内存

                Reserved的内存是指在虚拟内存地址中申请的内存页,并没有关联实际内存,所以不会对应用的内存占用产生什么实际的影响(在应用看来,它的内存区变的连续了)。所以这个rserve的内存大小一般和top的virt内存块对应。commit的内存是已经关联了物理内存(有的是物理内存,有的是磁盘的文件(swamp内存)),它和top的实际占用内存相关。

                Jcmd看到的commit内存总和是jvm层面实际分配的内存大小。 Pmap的RSS的总内存是应用在操作系统层面占用的总内存,应该和top里显示的是一致的(他们是commit的内存 除去 page out的内存)。          

https://docs.microsoft.com/zh-cn/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc

https://stackoverflow.com/questions/2440434/whats-the-difference-between-reserved-and-committed-memory

              https://zhanjindong.com/2016/03/02/jvm-memory-tunning-notes

 

 

jmap:提供dump,和统计JVM内存使用的一定粒度的统计信息(主要是堆内内存),更细粒度的信息需要使用专门的分析工具。

 

jinfo:查看或者动态设置单个或多个的JVM标志,但是jvm不一定会响应。

 

jstack:线程栈信息

 

Jstat:查看JVM的一些指标:比较常用的有gc回收的统计信息,还可以看classLoader,compiler,metaSpace等等的一些信息

 

性能分析工具:1. 采样分析类型  2. 探查分析类型

1. 采样分析类:按照一定的频率来进行统计。优点:对应用的性能损耗小。 缺点:统计信息可能不是很精确,可能会漏掉一些信息。 

2. 探查分析类:会对类的字节码进行加强,所以带来的性能损耗会比较大。优点是统计信息比较精确。

 

比较好用的采样类分析器:JFR+JMC

比较好用的dump分析器:MAT

 

gc日志也很重要,可以查看更细节的gc活动,不过有些细节的日志打印需要开启相关的jvm参数:

-XX:+PrintGCDetails 

-XX:+PrintAdaptiveSizePolicy 

 

pmap -x pid 从系统层面来查看应用的内存分配情况,包括c语言层面分配的native内存。

 

 

 

 

 

内存诊断经典例子:

https://tech.meituan.com/2019/01/03/spring-boot-native-memory-leak.html