为什么 MetaSpace Size 是 Used MetaSpace 的两倍?

Why MetaSpace Size is twice as big as Used MetaSpace?

我写了一个程序来模拟MetaSpace OOM。但是我发现 MetaSpace Size 几乎总是 Used MetaSpace 的两倍。为什么?

我 运行 我的程序带有标志 -XX:MaxMetaspaceSize=50m,当 Used MetaSpace 达到大约 25M 而不是 50M 时程序抛出 OOM,为什么?

好问题;-)

看看这篇不错的文章。

PermGenSpace vs MetaSpace

我认为以下两个实验将解释 MetaSpace SizeUsed MetaSpace 之间的差距意味着什么:

EXP-1:每个 ClassLoader 加载一个 class,我得到了这个:

EXP-2:每个 ClassLoader 加载五个 classes,我得到这个:

正如Java 8 document所说:

Space is requested from the OS and then divided into chunks. A class loader allocates space for metadata from its chunks (a chunk is bound to a specific class loader).

我认为这意味着一个块通常可以包含多个 class,因此 MetaSpace Size 的利用率随着每个 ClassLoader 加载更多 classes 而增长。

您可以通过 运行 code here 使用命令重现结果:

java -XX:MaxMetaspaceSize=50m MetadataOOMSimulator 100000000

注意:确保加载的所有classes不应该出现在CLASSPATH(通常包括当前目录),或者那些classes 将由 APPClassLoader 加载,而不是自定义的 ClassLoader。