我知道他们已经用 Java 8 中的 MetaSpace 替换了 PermGen。但我有几个问题:
MetaSpace默认是GC收集的吗?甚至 PermGen 也是通过添加 -XX:+CMSClassUnloadingEnabled 之类的 args 来收集的,那么 MetaSpace 有什么比 PermGen 更好的呢? MetaSpace 是基于本地内存的,所以它把 java 对象保存在磁盘上而不是 VM 上?甚至 MetaSpace 也会内存不足?如果再次这样,我将得到 OutOfMemoryException。默认情况下,MetaSpace 可以随着内存的增加而增长?
MetaSpace默认是GC收集的吗?
是的,GC 将在其满时在元空间上运行,它还将动态增加(允许)为元数据分配的内存。
甚至 PermGen 也是通过添加 -XX:+CMSClassUnloadingEnabled 之类的 args 来收集的,那么 MetaSpace 有什么比 PermGen 更好的呢?
改进在于元空间的动态扩展,这是 permgen 无法做到的。
MetaSpace 是基于本地内存的,所以它把 java 对象保存在磁盘上而不是 VM 上?
根据元空间的描述,它只使用本机内存(无分页)。
根据 Pierre - Hugues Charbonneau (link here) 的研究,很明显,元空间的引入并不一定能解决 OOM 问题,它充其量只是解决问题的方法,它试图动态调整元空间内存的大小以适应越来越多的类被加载,可能会导致无法控制的增长(只要本机内存允许)。
我们可以通过将 MaxMetaspaceSize
参数设置为 JVM 并运行提供的示例程序来实现著名的 OOM 错误。
非常感谢 Pierre-Hugues Charbonneau。
作为回应:
默认情况下,如果 Metaspace 内存达到 MaxMetaspaceSize,则会收集它。此参数最初是无限的。限制是您机器中的内存。但是当不再需要类和类加载器时,内存会自动释放。如果您怀疑 ClassLoader 有内存泄漏,您只需要调整此参数。 MetaSpece 使用本机内存,内存中的指针组织使得 GC 比旧的 PermGen 内存更快。不,这意味着 JVM 像普通 C 程序一样使用内存,并且不为 java 对象使用虚拟内存空间。那似乎内存仅受机器限制。请注意,如果需要,可以将机器的内存交换到磁盘。如果你设置参数 MaxMetaspaceSize 你可以得到 OutOfMemory ,如果你不设置这个参数你可以得到进程是否分配了所有的机器内存(包括交换空间)。
MetaspaceSize
而不是 MaxMetaspaceSize
MaxMetaspaceSize
而不是 MetaspaceSize
,则默认收集 Metaspace。
MetaSpace默认是GC收集的吗?一旦类元数据使用量达到“MaxMetaspaceSize”,默认为“无限制”,就会触发死类和类加载器的垃圾收集,因此需要适当的监控来限制此类 GC 的延迟或频率。甚至 PermGen 也是通过添加 -XX:+CMSClassUnloadingEnabled 之类的 args 来收集的,那么 MetaSpace 有什么比 PermGen 更好的呢?主要目标是删除 permgen,以便用户不必考虑正确调整它的大小。 MetaSpace 是基于本地内存的,所以它把 java 对象保存在磁盘上而不是 VM 上?磁盘不是本机内存,而是存储设备。本机内存,在这个上下文中是区域,是Java堆中剩余的进程的内存,甚至MetaSpace可以用完内存吗?是的,它受机器内存量的限制。
不定期副业成功案例分享