开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
前言
在Java 8中,方法区Metaspace取代了Permgen,那jvm为什么这么做呢?
Permgen
Permgen
代表永久世代。它是一种特殊类型的堆空间,与主内存堆分离。JVM使用Permgen
来跟踪加载的类元数据、静态内容(静态方法、对静态对象的引用等等)。
Permgen
的默认大小如下:
- 64MB: 32位JVM
- 82MB: 64位JVM
可以通过以下选项修改默认大小:
-XX:PermSize=[size]
是PermGen空间的初始或最小大小,例如:-XX:PermSize=512m
-XX:MaxPermSize=[size]
是最大的大小。例如:-XX:MaxPermSize=512m
由于其有限的内存大小,Permgen
会发生OutOfMemoryError。
Metaspace
元空间是Java 8中引入的一种新的内存空间。它已经取代了旧的永久代。永久代和元空间的主要区别在于,默认情况下,元空间会自动增加其大小,而永久生成总是有一个固定的最大大小。
通过引入Metaspace
,垃圾收集也得到了优化。一旦类元数据的使用达到其最大元空间大小,垃圾收集器将自动触发对不要的类进行清理。
可以通过设置以下选项中的一个或几个来调优Metaspace
:
-XX:MetaspaceSize=100M
: 设置元空间初始大小,当元空间达到这个大小时,会触发垃圾回收,根据收集结果,该大小随后可能会升高或降低。
-XX:MetaspaceSize=N
: 设置元空间的最大大小。-XX:InitialBootClassLoaderMetaspaceSize=32M
: 决定了给引导类加载器的第一个块的大小。它不施加任何限制,当那个块用完时,会分配一个新的块。-XX:MinMetaspaceFreeRatio=50
: 如果类元数据的提交可用空间占类元数据提交总空间的百分比小于MinMetaspaceFreeRatio
,则提高metspace GC的阈值,但阈值的增量大小必须满足MinMetaspaceFreeRatio
的要求,否则不提高阈值。-XX:MaxMetaspaceFreeRatio=80
:该参数的效果与MinMetaspaceFreeRatio相反。
-XX:MinMetaspaceExpansion=4M
: 增加metspace GC阈值时对增量大小的最小要求。- -XX:MaxMetaspaceExpansion=16M: 增加metspace GC阈值时对增量大小的最大要求。如果增量大小超过
MinMetaspaceExpansion
但小于MaxMetaspaceExpansion,则增量大小为MaxMetaspaceExpansion
。如果增量大小超过MaxMetaspaceExpansion,则增量大小为MinMetaspaceExpansion
+原始增量大小。
因此,通过这种改进,JVM减少了OutOfMemory的可能。