JVM之元空间和永久代
概述
在hotspot下,从jdk7开始逐渐消除永久代,jdk8时元空间完全取代永久代
永久代
永久代也叫方法区,这是一片连续的堆空间,用来存放加载的类信息、访问修饰符、常量池、字段描述、方法描述等。
-XX:MaxPerSize
-XX:PerSize
可以限制永久代的大小,我们可以通过限制其大小来限制常量池大小。通常常量池溢出时,也会在OutofMemoryError异常后面紧跟PermGen space。随着动态类加载情况越来越多,这块连续的内存空间开始变得不太可控,设置小了容易内存泄漏,大了浪费内存,于是元空间出现了。
元空间
元空间(MetaSpace),元空间分为Klass MetaSpace 和 NoKlass MetaSpace。
Klass MetaSpace
Klass MetaSpace 是存放Klass的连续内存空间,Klass是class文件在JVM里运行时的数据结构,类似A.class文件存在heap的对象实例。
它的大小由:
-XX:CompressedClassSpaceSize控制,默认为1G
NoKlass MetaSpace
存放Klass的其他相关文件,例如:method、constantPool,是一片不连续的空间,在本地内存中分配。
jdk8以后永久代完全退出历史舞台,元空间登场,作为替代者,为了预防一些破坏性操作,如类似持续创建新类型的测试类(GGLib技术,如:Spring,Hibernate等)在元空间下增强的类已经很难产生溢出异常;提供了一些参数作为预防措施:
-XX:MaxMetaSpace:设置元空间的最大值,默认-1(不限制)。
-XX:MetaspaceSize:设置初始空间大小,以字节为单位,触发该值时会触发垃圾收集进行类型卸载,同时收集齐会对该值进行调整:释放大量空间就会适当降低该值;释放很小空间就会适当提高该值。
-XX:MinMetaspaceFreeRatio:控制垃圾收集后最小的元空间剩余容量的百分比,降低元空间不足导致的垃圾收集频率。