有一台服务器,我无法运行任何基于GUI的分析器(如jvisualvm)来监视正在运行的Java进程的堆。根据{{3}},我可以使用jstat -gc <pid>
并查看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显示堆使用和分配的不同数字?
答案 0 :(得分:3)
对于Java 8, jstat 实用程序已更新,
jstat –gc <PID>
在输出中包含以下字段:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
39936.0 29184.0 0.0 29035.4 273920.0 170661.5 699392.0 39235.9 98480.0 97022.7 8624.0 8163.3 63 0.925 38 2.363 3.289
堆使用
要获取当前堆使用情况,大约是jVisualJM中的值,需要添加以下值:
S0U: Survivor space 0 utilization (kB)
S1U: Survivor space 1 utilization (kB)
EU: Eden space utilization (kB)
OU: Old space utilization (kB)
看Java 8 Virtual Machine Garbage Collection Tuning Guide, 堆似乎是由'Young'代(Eden&amp; Survivor 0&amp; 1空格)和'Old'代(旧空间)组成。
元空间使用
要获取当前元空间使用量,大约是jVisualJM中的值,需要以下大小:
MU: Metaspace utilization (kB)
备注强>
无论出于何种原因,我都无法在jstat和jVisualJM之间获得完全相同的值,但足够接近允许两个工具都可以放心使用。
JVM内存池
有关JVM内存池的更多详细信息,请参阅此StackOverflow question & answer,其中包含Java 7&amp; 8。
Java 8 Using JConsole guide中也有一些信息,但令人惊讶的是,这仍然提到了Java 7 Permanent Generation空间而不是Java 8 Metaspace。
答案 1 :(得分:0)
事实证明,添加jstat的EU和OU列大约等于jvisualvm中显示的堆使用情况。对于我正在监控的流程,EU + OU总是比jvisualvm中显示的要少12 MB。 (在我的问题中提供的示例中,jvisualvm显示506 MB的堆使用情况,jstat显示EU + OU = 240 MB。所以我必须在堆使用率下降到250 MB之后立即运行jstat。)
添加jstat的EC和OC列大约等于jvisualvm中显示的堆分配。对于我正在监控的流程,EC + OC比jvisualvm中显示的要少45-60 MB。
答案 2 :(得分:0)
easy unix命令通过jstat查看当前保留的堆大小:(它匹配jconsole数字)
jstat -gc <pid> 3000 | awk '{split($0,a," "); print a[3]+a[4]+a[6]+a[8]}'