我写了一个程序来模拟 MetaSpace OOM。但我发现它MetaSpace Size
几乎总是Used MetaSpace
. 为什么?
我用 flag 运行我的程序,程序在达到大约 25M 而不是 50M-XX:MaxMetaspaceSize=50m
时抛出 OOM ,为什么?Used MetaSpace
我写了一个程序来模拟 MetaSpace OOM。但我发现它MetaSpace Size
几乎总是Used MetaSpace
. 为什么?
我用 flag 运行我的程序,程序在达到大约 25M 而不是 50M-XX:MaxMetaspaceSize=50m
时抛出 OOM ,为什么?Used MetaSpace
我认为以下两个实验将解释MetaSpace Size和Used MetaSpace之间的差距是什么意思:
EXP-1:每个 ClassLoader 加载一个类,我得到了这个:
EXP-2:每个 ClassLoader 加载五个类,我得到了这个:
正如Java 8 文档所说:
从操作系统请求空间,然后分成块。类加载器从其块中为元数据分配空间(块绑定到特定的类加载器)。
我认为这意味着一个块通常可以包含多个类,因此 MetaSpace Size 的利用率会随着每个 ClassLoader 加载更多类而增长。
您可以通过在此处使用命令运行代码来重新显示结果:
java -XX:MaxMetaspaceSize=50m MetadataOOMSimulator 100000000
注意:确保所有被加载的类都不应该出现在CLASSPATH
(通常包括当前目录),否则这些类将由 APPClassLoader 而不是自定义的 ClassLoader 加载。