JDK1.8 方法区的变化

方法区的垃圾回收主要分为两部分:常量池中废弃的常量和不再使用的类

JDK1.8 方法区的变化

JDK1.7 vs JDK1.8

  • 在JDK1.7及以前,HotSpot虚拟机将Java类信息、常量池、静态变量、即时编译器编译后的代码等数据,存储在Perm(永久带)里(对于其他虚拟机如BEA JRockit、IBM J9等是不存在永久带概念的),类的元数据和静态变量在类加载的时候被分配到Perm里,当常量池回收或者类被卸载的时候,垃圾收集器会回收这一部分内存,但效果不太理想。
  • JDK 1.8中则把永久代给完全删除了,取而代之的是MetaSpace,将类元数据放到了本地内存中,将常量池和静态变量放到了Java堆里,HotSpot VM将会为类的元数据明确的分配与释放本地内存,在这种架构下,类元数据就突破了-XX:MaxPermSize的限制,所以此配置已经失效,现在可以使用更多的本地内存。这样一定程度上解决了原来在运行时生成大量的类,从而经常Full GC的问题——如运行时使用反射、代理等。
  • 方法区是JVM 的规范,永久代PermHotspot 对这种规范的实现
  • 为什么Jdk1.8要把方法区从JVM里(永久代)移到直接内存(元空间)?
  1. 字符串存在永久代中,容易出现性能问题和内存溢出。
  2. 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难。
  3. 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。