我正在调查OutOfMemoryError:压缩类空间问题。我认为,我找到了它的根本原因和解决方案(Hibernate Validator方法调用的JAXBContext.newInstance():在用户每次提交操作后调用buildValidatorFactory),但是在研究过程中,我注意到了一件令人困惑的事情。
我试图运行jcmd VM.native_memory和jstat -gc来跟踪类的提交大小和CCSU(压缩的类空间使用情况:]
d:\experiments>jcmd 59692 VM.native_memory summary
Native Memory Tracking:
Total: reserved=10039335KB, committed=889895KB
- Java Heap (reserved=8353792KB, committed=522240KB)
(mmap: reserved=8353792KB, committed=522240KB)
- Class (reserved=1072460KB, **committed=24268KB**)
(classes #2518)
(malloc=9548KB #2393)
(mmap: reserved=1062912KB, committed=14720KB)
和
d:\experiments>jstat -gc 59692 2s
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
21504,0 21504,0 0,0 0,0 131072,0 56218,7 139264,0 7755,5 14976,0 14318,5 1920,0 1721,7 2 0,012 1 0,036 - - 0,048
我希望NMT中的“ Class commit”度量与jstat中的CCSU之间没有主要区别,但是jstat显示,与“ Class Committed”相比,已用内存只有约1.72 MB,超过了24 MB。因此,我生成了GC.class_stats统计信息,它表明KlassBytes大约为1738616 B-> 1,739 MB-因此它的值与jstat在CCSU中显示的值大致相同。我还发现其余的元数据(如方法,常量等)占用了约14,44 MB(这与mmap中的值大致相同:committed = 14720KB-但我不知道这个数字是多少)。
那么其余的呢? NMT给出的确切数字是多少?
Class
”部分显示Metaspace和Compressed Class Space的合计数字。 [[Metaspace和Compressed Class Space之间的差异在here中进行了说明。
Memory Footprint of a Java Process演示文稿中的幻灯片
MC
,MU
,CCSC
和CCSU
代表Capacity和Used之间的关系在this answer中进行了说明。
因此,本机内存跟踪显示的Class Committed与具有以下不等式的jstat度量有关:Class Committed >= MC + CCSC >= MU + CCSU
但是,它们之间的差异可以是任意大的。
自JDK 10起,本机内存跟踪报告显示了
Class
部分的详细细分:- Class (reserved=1073841KB, committed=28593KB) (classes #3967) ( instance classes #3694, array classes #273) (malloc=689KB #9228) (mmap: reserved=1073152KB, committed=27904KB) ( Metadata: ) ( reserved=24576KB, committed=24576KB) ( used=24131KB) ( free=445KB) ( waste=0KB =0.00%) ( Class space:) ( reserved=1048576KB, committed=3328KB) ( used=3003KB) ( free=325KB) ( waste=0KB =0.00%)