为了优化 JVM 性能、简化 Java 应用的内存管理,并解决因为永久代有固定大小限制而导致的内存溢出问题。为此,在JDK升级过程中,逐渐用元空间取代了永久带。这样,JVM 的垃圾收集器可以更高效地管理内存,尤其是在处理大量动态生成类的应用程序时(例如,使用大量反射或动态代理技术的应用)。
为了更好的演示不同版本的JDK内存区域的不同,帅旋这里特意画了几张图来说明。
JDK 6:使用永久代实现方法区
在 JDK 1.6 中,方法区主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
方法区是 JVM 规范的一部分,而“永久代”(PermGen space)是 HotSpot JVM 对方法区的实现,这是一个固定大小的内存区域。
永久代的问题在于它有一个固定的内存限制,这使得如果加载了大量类或大量使用字符串的应用可能会遇到内存溢出错误。
常量池包括类常量池和运行时常量池,运行时常量池逻辑上包含字符串常量池。
JDK 7:逐步移除永久代
JDK 1.7 开始了去永久代化的过程,尽管永久代仍然存在,但已经将字符串常量池从运行时常量池剖离开来了,从永久代移至 Java 堆中。
JDK 8:彻底去除永久代,引入元空间(MetaSpace)
到了 JDK 1.8,永久代被完全移除,取而代之的是元空间(MetaSpace)。元空间不在虚拟机内存中而是使用本地内存。类常量池和运行时常量池都移动到了元空间。
静态变量也在堆中分配。