jstat 和 jcmd 对元空间内存给出了不同的答案
jstat and jcmd giving different answers for metaspace memory
我目前正在调查压缩的 class space 问题。我知道问题出在哪里,但在调查时,我注意到 jstat -gc ...
和 jcmd ... GC.heap_info
给出了不同数量的元 space 和压缩 class space 容量和使用:
▶ jcmd 32152 GC.heap_info
32152:
PSYoungGen total 153600K, used 129316K [0x00000000eab00000, 0x00000000f5b00000, 0x0000000100000000)
eden space 137728K, 91% used [0x00000000eab00000,0x00000000f26abf48,0x00000000f3180000)
from space 15872K, 16% used [0x00000000f4100000,0x00000000f439d428,0x00000000f5080000)
to space 15872K, 0% used [0x00000000f3180000,0x00000000f3180000,0x00000000f4100000)
ParOldGen total 290816K, used 21446K [0x00000000c0000000, 0x00000000d1c00000, 0x00000000eab00000)
object space 290816K, 7% used [0x00000000c0000000,0x00000000c14f1ac0,0x00000000d1c00000)
Metaspace used 59690K, capacity 64980K, committed 65192K, reserved 1103872K
class space used 9289K, capacity 10116K, committed 10152K, reserved 1048576K
▶ jstat -gc 32152
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
15872.0 15872.0 2677.0 0.0 137728.0 126711.2 290816.0 21446.7 63400.0 58060.7 9896.0 9067.2 8 0.047 3 0.118 0.164
堆容量的数字似乎大体匹配(幸存者、伊甸园和老一代所有容量都一致)。堆使用数字不完全匹配,但我不希望它们匹配; jstat
是在 jcm
之后大约一秒钟收集到的。但是 metaspace 数字全部关闭,jstat
数字通常略低于 jcmd
数字。我重新运行这两个命令以确认调用之间没有发生 class 加载,事实上,这两个命令都为 metaspace 数字提供了与以前相同的输出。
这是怎么回事?他们衡量这些数字的方式是否略有不同?哪个更准确?
运行时信息:
JVM: Java HotSpot(TM) 64-Bit Server VM (25.202-b08, mixed mode)
Java: version 1.8.0_202, vendor Oracle Corporation
-Xmx1024m
-XX:+UseParallelGC
抓得好!数字确实不同:jstat 值可能会稍微落后,因为它们是 updated only after GC,而 jcmd 值始终是最新的。
所以,jcmd GC.heap_info
应该更准确。
另请注意,jstat 输出中的 MC
对应于元空间提交的大小,而不是容量。
我目前正在调查压缩的 class space 问题。我知道问题出在哪里,但在调查时,我注意到 jstat -gc ...
和 jcmd ... GC.heap_info
给出了不同数量的元 space 和压缩 class space 容量和使用:
▶ jcmd 32152 GC.heap_info
32152:
PSYoungGen total 153600K, used 129316K [0x00000000eab00000, 0x00000000f5b00000, 0x0000000100000000)
eden space 137728K, 91% used [0x00000000eab00000,0x00000000f26abf48,0x00000000f3180000)
from space 15872K, 16% used [0x00000000f4100000,0x00000000f439d428,0x00000000f5080000)
to space 15872K, 0% used [0x00000000f3180000,0x00000000f3180000,0x00000000f4100000)
ParOldGen total 290816K, used 21446K [0x00000000c0000000, 0x00000000d1c00000, 0x00000000eab00000)
object space 290816K, 7% used [0x00000000c0000000,0x00000000c14f1ac0,0x00000000d1c00000)
Metaspace used 59690K, capacity 64980K, committed 65192K, reserved 1103872K
class space used 9289K, capacity 10116K, committed 10152K, reserved 1048576K
▶ jstat -gc 32152
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
15872.0 15872.0 2677.0 0.0 137728.0 126711.2 290816.0 21446.7 63400.0 58060.7 9896.0 9067.2 8 0.047 3 0.118 0.164
堆容量的数字似乎大体匹配(幸存者、伊甸园和老一代所有容量都一致)。堆使用数字不完全匹配,但我不希望它们匹配; jstat
是在 jcm
之后大约一秒钟收集到的。但是 metaspace 数字全部关闭,jstat
数字通常略低于 jcmd
数字。我重新运行这两个命令以确认调用之间没有发生 class 加载,事实上,这两个命令都为 metaspace 数字提供了与以前相同的输出。
这是怎么回事?他们衡量这些数字的方式是否略有不同?哪个更准确?
运行时信息:
JVM: Java HotSpot(TM) 64-Bit Server VM (25.202-b08, mixed mode)
Java: version 1.8.0_202, vendor Oracle Corporation
-Xmx1024m
-XX:+UseParallelGC
抓得好!数字确实不同:jstat 值可能会稍微落后,因为它们是 updated only after GC,而 jcmd 值始终是最新的。
所以,jcmd GC.heap_info
应该更准确。
另请注意,jstat 输出中的 MC
对应于元空间提交的大小,而不是容量。