MetaSpace在Java 8中的用途是什么?

2022-08-31 15:25:47

我知道他们已经用Java 8中的MetaSpace取代了PermGen。但我有几个问题:

  1. 默认情况下,MetaSpace是GC收集的吗?
  2. 即使是PermGen也是通过添加args来收集GC的,那么是什么让MetaSpace比PermGen更好呢?-XX:+CMSClassUnloadingEnabled
  3. MetaSpace基于本机内存,因此它将Java对象保存在磁盘上而不是VM上?
  4. 甚至MetaSpace也会耗尽内存吗?如果是这样,我会得到.OutOfMemoryException
  5. 默认情况下,MetaSpace可以随着内存的增加而增长吗?

答案 1

默认情况下,MetaSpace是GC收集的吗?

是的,当 GC 满时,它将在元空间上运行,它还会动态增加(在允许的情况下)为元数据分配的内存。

即使是PermGen也是通过添加诸如-XX:+CMSClassUnloadingEnabled之类的参数来收集GC的,那么是什么让MetaSpace比PermGen更好呢?

改进之处在于元空间的动态扩展,这是permgen无法做到的。

MetaSpace基于本机内存,因此它将Java对象保存在磁盘上而不是VM上?

根据元空间的描述,它只使用本机内存(不分页)。

根据Pierre - Hugues Charbonneau的研究(链接在这里),很明显,元空间的引入并不一定能解决OOM问题,它充其量只是问题的创可贴,它试图动态调整元空间内存的大小以适应越来越多的类,这些类被加载了不受控制地增长的可能副作用(只要本机内存允许)。

我们可以通过将参数设置为 JVM 并运行提供的示例程序来实现著名的 OOM 错误。MaxMetaspaceSize

非常感谢皮埃尔 - 雨果夏邦诺。


答案 2

作为回应:

  1. 默认情况下,如果 Metaspace 内存达到 MaxMetaspaceSize,则会收集它。此参数最初是无限制的。限制是计算机中的内存。但是,当不再需要类和类装入器时,内存会自动释放。仅当您怀疑 ClassLoader 存在内存泄漏时,才需要调整此参数。

  2. MetaSpece 使用本机内存,内存中带有指针的组织使得 GC 比较旧的 PermGen 内存更快。

  3. 不,这意味着JVM像普通的C程序一样使用内存,并且不对java对象使用虚拟内存空间。似乎内存仅受机器的限制。请注意,如果需要,可以将计算机的内存交换到磁盘。

  4. 如果设置了参数 MaxMetaspaceSize,则可以获取 OutOfMemory,如果不设置此参数,则可以在进程分配所有计算机内存(包括交换空间)时获取。