Java8新特性 - metaspace

Louis2020-09-04Java技术JavaJava8

Java8移除了永久代,新增了metaspace。

Java7中的永久代

在JVM规范第7版中,把内存分为以下5个区域:

  • 方法区 Method Area
  • 堆 Heap
  • 虚拟机栈 VM Stack
  • 本地方法栈 Native Method Stack
  • 程序计数器 Program Counter Register

方法区是线程共享的内存区域,用于存储类信息、常量、静态变量等。

各个虚拟机对内存管理的实现方式可能略有不同,以最常见的HotSpot虚拟机为例,把虚拟机栈和本地方法栈合二为一了,并使用了永久代(Permanent Generation) 来实现方法区。

TIP

原本常量池是放在永久代的,但在JDK1.7的HotSpot中已经把字符串常量池移到了堆中

涉及永久代的参数: -XX:PermSize=256M -XX:MaxPermSize=256M

永久代的缺陷

HotSpot使用永久代来实现方法区,本意是想让垃圾收集器像管理Java堆一样管理方法区,而避免为方法区再写一个垃圾收集器。

然而这样做带来了其他问题:

  1. 容易造成永久代内存溢出
  2. 由于方法区主要存储类信息,因此对方法区的垃圾回收主要是回收已卸载的类型,而类的回收条件非常苛刻,通常回收效果并不理想

TIP

其他虚拟机,例如Oracle JRockit、IBM J9没有永久代概念。

Metaspace

在java8中,准确说是在HotSpot虚拟机中移除了永久代,而使用元空间(Metaspace) 来存储类元数据信息。元空间使用的是本地内存,可以使用-XX:MetaspaceSize和-XX:MaxMetaspaceSize调整元空间的大小,默认初始大小约21M,最大值不限制。

Metaspace会为每个类加载器及其加载过的类单独分配内存,通过以下几个命令可以查看Metaspace的空间占用情况。

  1. jmap -heap <pid>
  2. jmap -clstats <pid>
  3. jstat -gc <pid>
Last Updated 2024/11/24 20:50:53