方法区的演进细节
-
首先明确,只有HotSpot才有永久代,JRockit,IBM,J9等,是不存在永久代的概念的,原则上如何实现方法区属于虚拟机实现细节,不受Java虚拟机规范约束,并不要求统一
-
随着Java8的到来,HotSpot VM将永久代中的元数据信息移到了一个与堆不相连的本地内存区域,这个区域叫做元空间(Metaspace)
-
HotSpot中方法区的变化
-
jdk1.6及以前 有永久代(Permanent Generation) jdk1.7 有永久代,但已经逐步"去永久代",字符串常量池,静态变量移除,保存在堆中 jdk1.8及以后 **无永久代,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池,静态变量仍在堆 **
-
永久代为什么要被元空间替换?
- 为永久代设置空间大小是很难确定的
- 在某些场景下,如果动态加载类过多,容易产生Perm区的OOM,比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,可能出现OOM,而元空间和永久代之间最大的区别在于,元空间并不在虚拟机中,而是使用本地内存,因此,默认情况下,元空间的大小仅受本地内存限制
- 对永久代进行调优是很困难的
StringTable(String Pool)为什么要调整?
- jdk7中将StringTable放到堆空间中,因为永久代的回收效率很低,在full gc的时候才会触发,而full gc是老年代或永久代空间不足时才会触发,这就导致StringTable回收效率不高,而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足,放到堆里,能及时回收内存