Java Jstat和Jvisualvm显示堆使用/分配的不同数字

Java Jstat和Jvisualvm显示堆使用/分配的不同数字,java,profiling,heap,Java,Profiling,Heap,有一台服务器,我无法在其上运行任何基于GUI的探查器(如jvisualvm)来监视正在运行的Java进程的堆。根据,我可以使用jstat-gc并查看OU和OC列以了解堆的使用和分配 但我只是比较了另一台服务器上的jvisualvm和jstat,它们在堆使用和分配方面的数字并不相同 Jvisualvm显示,Java进程为堆分配了大约1GB的内存,使用了大约500MB的内存: 但对于同一流程,jstat在OC列下仅显示约700MB,在OU列下显示约226MB: # jstat -gc 39621

有一台服务器,我无法在其上运行任何基于GUI的探查器(如jvisualvm)来监视正在运行的Java进程的堆。根据,我可以使用
jstat-gc
并查看OU和OC列以了解堆的使用和分配

但我只是比较了另一台服务器上的jvisualvm和jstat,它们在堆使用和分配方面的数字并不相同

Jvisualvm显示,Java进程为堆分配了大约1GB的内存,使用了大约500MB的内存:

但对于同一流程,jstat在OC列下仅显示约700MB,在OU列下显示约226MB:

# jstat -gc 39621
S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
16384.0 17920.0 3984.0  0.0   322560.0 10320.4   699392.0   226295.2  83968.0 47921.1  11966   66.103  12      3.083   69.186

为什么jvisualvm和jstat显示不同的堆使用率和分配数?

结果表明,将jstat的EU和OU列相加大约等于jvisualvm中显示的堆使用率。对于我正在监视的流程,EU+OU总是比jvisualvm中显示的少约12MB。(在我问题中提供的示例中,jvisualvm显示506MB的堆使用率,jstat显示EU+OU=240MB。因此,我必须在堆使用率降至250MB之后立即运行jstat。)


将jstat的EC和OC列相加大约等于jvisualvm中显示的堆分配。对于我正在监视的进程,EC+OC大约比jvisualvm中显示的要少45-60 MB。

对于Java 8,jstat实用程序已经更新,并且

jstat –gc <PID>
堆使用情况

要获取当前堆的使用情况(大约为jVisualJM中的值),需要添加以下值:

S0U: Survivor space 0 utilization (kB)

S1U: Survivor space 1 utilization (kB)

EU: Eden space utilization (kB)

OU: Old space utilization (kB)
看,, 堆似乎由“年轻”一代(伊甸园和幸存者0&1空间)和“老”一代(旧空间)组成

元空间使用情况

要获取当前的元空间使用情况(大约为jVisualJM中的值),需要以下大小:

MU: Metaspace utilization (kB)
注释

无论出于何种原因,我一直无法在jstat和jVisualJM之间获得完全相同的值,但距离足够近,可以放心地使用这两个工具

JVM内存池

有关JVM内存池的更多详细信息,请参阅本文,其中介绍了Java7和Java8


中也有一些信息,但令人惊讶的是,这仍然提到了Java 7永久生成空间,而不是Java 8元空间。

easy unix命令可通过jstat查看当前保留的堆大小:(它与jconsole编号匹配)

jstat-gc3000 | awk'{split($0,a,“”);打印a[3]+a[4]+a[6]+a[8]}
MU: Metaspace utilization (kB)
jstat -gc <pid> 3000 | awk '{split($0,a," "); print a[3]+a[4]+a[6]+a[8]}'