【Do家】通过pmap命令解读jvm内存占用情况
1、执行Linux的pmap命令,采集到如下数据:
87: /usr/local/java/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xms4G -Xmx4G -Xmn1G -Xss512k -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024
Address Kbytes PSS Dirty Swap Mode Mapping
0000000000400000 4 1 0 0 r-xp /usr/local/java/jre/bin/java
0000000000600000 4 4 4 0 r--p /usr/local/java/jre/bin/java
0000000000601000 4 4 4 0 rw-p /usr/local/java/jre/bin/java
0000000002271000 6392 6196 6196 0 rw-p [heap]
00000006c0800000 4221440 3285332 3285332 0 rw-p [ anon ]
00000007c2280000 1021440 0 0 0 ---p [ anon ]
00007f6a0d22a000 1280 996 996 0 rw-p [ anon ]
00007f6a0d36a000 768 0 0 0 ---p [ anon ]
00007f6a0d42a000 2048 1980 1980 0 rw-p [ anon ]
00007f6a0d62a000 2048 2044 2044 0 rw-p [ anon ]
00007f6a0d82a000 2048 2040 2040 0 rw-p [ anon ]
00007f6a0da2a000 2048 2044 2044 0 rw-p [ anon ]
00007f6a0dc2a000 12 0 0 0 ---p [ anon ]
00007f6a0dc2d000 504 8 8 0 rw-p [ anon ]
00007f6a0dcab000 12 0 0 0 ---p [ anon ]
00007f6a0dcae000 504 12 12 0 rw-p [ anon ]
00007f6a0dd2c000 12 0 0 0 ---p [ anon ]
00007f6a0dd2f000 504 8 8 0 rw-p [ anon ]
00007f6a0ddad000 12 0 0 0 ---p [ anon ]
00007f6a0ddb0000 504 8 8 0 rw-p [ anon ]
00007f6a0de2e000 12 0 0 0 ---p [ anon ]
2、通过os命令分析Java进程中包含线程数据
Threads: 292
298
线程数量:292
3、通过status统计的Java进程实际物理内存占用,参见VmRSS参数
VmPeak: 12399068 kB
VmSize: 12289588 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 3105500 kB
VmRSS: 3103724 kB
VmData: 7152972 kB
VmStk: 244 kB
VmExe: 4 kB
VmLib: 18152 kB
VmPTE: 6700 kB
VmSwap: 0 kB
VmRSS=>3103724KB
4、通过pmap统计的Java进程实际占用物理内存,参见PSS参数
total 12289592 3098242 3078148
PSS=>3098242
5、解读如下:
1> JVM中heap占用空间,体现为:
00000006c0800000 4221440 3285332 3285332 0 rw-p [ anon ]
主要关注PSS这列,由于heap采用了固定大小,-Xms4G -Xmx4G,os预留给Java进程的Heap大小为:4221440KB
2> JVM中CompressedClassSpaceSize,体现为:
00000007c2280000 1021440 0 0 0 ---p [ anon ]
JVM默认的参数CompressedClassSpaceSize,压缩的类空间大小为1024KB
3> JVM中线程的栈占用的空间大小,512KB,即通过参数控制-Xss512k,体现为:
00007f6a0dc2d000 504 8 8 0 rw-p [ anon ]
00007f6a0dcab000 12 0 0 0 ---p [ anon ]
由于线程栈是每个线程独占的,占用空间取决于线程的数量,所以会出现重复的该数据段。
4> 其他的MetaSpace和本地内存使用,在pmap也有对应分配地址体现
【小结】
1> PSS实际上稍大于RSS,都是体现Java进程实际占用的物理内存大小;
2> 如果Java进程占用物理内存利用率高,与是否FGC无关;考虑线程数波动和本地内存的消耗,一般Heap都是固定大小的;
3> 从os角度,内存划分给Java进程后,即便是空间回收了,但是os也会预留该空间,认为此空间由进程使用中;
4> mapping为anon,即anonymous memory mappings,匿名内存映射,由os动态分配内存出去的空间;
Linux代码
- # pmap -x 87|more
# pmap -x 87|more
87: /usr/local/java/jre/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xms4G -Xmx4G -Xmn1G -Xss512k -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024
Address Kbytes PSS Dirty Swap Mode Mapping
0000000000400000 4 1 0 0 r-xp /usr/local/java/jre/bin/java
0000000000600000 4 4 4 0 r--p /usr/local/java/jre/bin/java
0000000000601000 4 4 4 0 rw-p /usr/local/java/jre/bin/java
0000000002271000 6392 6196 6196 0 rw-p [heap]
00000006c0800000 4221440 3285332 3285332 0 rw-p [ anon ]
00000007c2280000 1021440 0 0 0 ---p [ anon ]
00007f6a0d22a000 1280 996 996 0 rw-p [ anon ]
00007f6a0d36a000 768 0 0 0 ---p [ anon ]
00007f6a0d42a000 2048 1980 1980 0 rw-p [ anon ]
00007f6a0d62a000 2048 2044 2044 0 rw-p [ anon ]
00007f6a0d82a000 2048 2040 2040 0 rw-p [ anon ]
00007f6a0da2a000 2048 2044 2044 0 rw-p [ anon ]
00007f6a0dc2a000 12 0 0 0 ---p [ anon ]
00007f6a0dc2d000 504 8 8 0 rw-p [ anon ]
00007f6a0dcab000 12 0 0 0 ---p [ anon ]
00007f6a0dcae000 504 12 12 0 rw-p [ anon ]
00007f6a0dd2c000 12 0 0 0 ---p [ anon ]
00007f6a0dd2f000 504 8 8 0 rw-p [ anon ]
00007f6a0ddad000 12 0 0 0 ---p [ anon ]
00007f6a0ddb0000 504 8 8 0 rw-p [ anon ]
00007f6a0de2e000 12 0 0 0 ---p [ anon ]
2、通过os命令分析Java进程中包含线程数据
Linux代码
- # cat /proc/87/status |grep Threads
# cat /proc/87/status |grep Threads
Threads: 292
Linux代码
- # pmap -x 87 |awk -F' ' '{print $2}' |grep 504 |wc -l
# pmap -x 87 |awk -F' ' '{print $2}' |grep 504 |wc -l
298
线程数量:292
3、通过status统计的Java进程实际物理内存占用,参见VmRSS参数
Linux代码
- # cat /proc/88/status |grep Vm
# cat /proc/88/status |grep Vm
VmPeak: 12399068 kB
VmSize: 12289588 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 3105500 kB
VmRSS: 3103724 kB
VmData: 7152972 kB
VmStk: 244 kB
VmExe: 4 kB
VmLib: 18152 kB
VmPTE: 6700 kB
VmSwap: 0 kB
VmRSS=>3103724KB
4、通过pmap统计的Java进程实际占用物理内存,参见PSS参数
Linux代码
- # pmap -x 88 |grep total
# pmap -x 88 |grep total
total 12289592 3098242 3078148
PSS=>3098242
5、解读如下:
1> JVM中heap占用空间,体现为:
00000006c0800000 4221440 3285332 3285332 0 rw-p [ anon ]
主要关注PSS这列,由于heap采用了固定大小,-Xms4G -Xmx4G,os预留给Java进程的Heap大小为:4221440KB
2> JVM中CompressedClassSpaceSize,体现为:
00000007c2280000 1021440 0 0 0 ---p [ anon ]
JVM默认的参数CompressedClassSpaceSize,压缩的类空间大小为1024KB
3> JVM中线程的栈占用的空间大小,512KB,即通过参数控制-Xss512k,体现为:
00007f6a0dc2d000 504 8 8 0 rw-p [ anon ]
00007f6a0dcab000 12 0 0 0 ---p [ anon ]
由于线程栈是每个线程独占的,占用空间取决于线程的数量,所以会出现重复的该数据段。
4> 其他的MetaSpace和本地内存使用,在pmap也有对应分配地址体现
【小结】
1> PSS实际上稍大于RSS,都是体现Java进程实际占用的物理内存大小;
2> 如果Java进程占用物理内存利用率高,与是否FGC无关;考虑线程数波动和本地内存的消耗,一般Heap都是固定大小的;
3> 从os角度,内存划分给Java进程后,即便是空间回收了,但是os也会预留该空间,认为此空间由进程使用中;
4> mapping为anon,即anonymous memory mappings,匿名内存映射,由os动态分配内存出去的空间;