JDK1.7和1.8的JVM运行时数据区域(JVM内存模型)的主要区别

关于JVM的运行时数据区域,如果不了解的,可以看上一篇文章:JDK1.7的JVM运行时数据区域(JVM内存模型)详解
下面主要讲解JDK1.7与JDK1.8的JVM运行时数据区域的主要区别,关于字符串常量的区别,同样在上一篇文章中:JDK1.7的JVM运行时数据区域(JVM内存模型)详解

1 对比图

在这里插入图片描述

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

4.2 为什么移除永久代?

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

4.3 为什么要引入元空间

  1. 字符串常量存在永久代中,容易出现性能问题和内存溢出。
  2. 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
  3. 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
  4. Oracle 可能会将HotSpot与Jrockit两种虚拟机合二为一。
发布了58 篇原创文章 · 获赞 105 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43767015/article/details/105189239