JDK 1.7 和 JDK 1.8 运行时数据结构

1 对比图

JDK 1.7 和 JDK 1.8 运行时数据结构_第1张图片
image.png

2 方法区的变化

JDK1.8 与JDK1.7 最大的区别是:JDK1.8 将永久代取消,取而代之的是元空间,在 JDK1.8 中方法区是由元空间来实现,所以原来属于方法区的运行时常量池就属于元空间了。
  元空间属于本地内存,所以元空间的大小仅受本地内存限制,但是可以通过 -XX:MaxMetaspaceSize 进行增长上限的最大值设置,默认值为 4G,元空间的初始空间大小可以通过 -XX:MetaspaceSize 进行设置,默认值为 20.8M,还有一些其他参数可以进行设置,元空间大小会自动进行调整。

3 数据的迁移

  • 在 JDK1.7 之前运行时常量池,字符串常量池,静态域等存放在方法区, 运行时常量池逻辑包含字符串常量池,此时hotspot虚拟机对方法区的实现为永久代。
  • 在 JDK1.7 中字符串常量池和静态域被从方法区(永久代)拿到了堆中(在堆中另开辟了一块空间),这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区,也就是 HotSpot 中的永久代。
  • 在 JDK1.8 中 HotSpot 移除了永久代,用元空间(Metaspace)取而代之, 这时候字符串常量池还在堆,运行时常量池还在方法区,只不过方法区的实现从永久代变成了元空间(Metaspace)。

4 元空间简介

用于存储已被虚拟机加载的类元数据,符号引用,即包括运行时常量池。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。

不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:-XX:MetaspaceSize

4.1 元数据

元数据(Meta Data),关于数据的数据或者叫做用来描述数据的数据或者叫做信息的信息。
  这些定义都很是抽象,我们可以把元数据简单的理解成,最小的数据单位。元数据可以为数据说明其元素、属性(名称、大小、数据类型、等),、结构(长度、字段、数据列)、相关数据(位于何处、如何联系、拥有者)等。

4.2 为什么移除永久代?

  • 由于永久代使用 JVM 内存经常不够用或发生内存泄露,引发恼人的 OutOfMemoryError 异常(在 Java Web 开发中非常常见)。
  • 移除永久代可以促进 HotSpotJRockit 两种虚拟机的融合,因为 JRockit 没有永久代。
  • 对永久代进行调优是很困难的。永久代中的元数据可能会随着每一次Full GC发生而进行移动。

4.3 为什么要引入元空间?

  • 字符串常量存在永久代中,容易出现性能问题和内存溢出。
  • 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  • 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
  • Oracle 可能会将HotSpot与Jrockit两种虚拟机合二为一。

你可能感兴趣的:(JDK 1.7 和 JDK 1.8 运行时数据结构)