面试官,Java8 JVM内存结构变了,永久代到元空间
在文章《JVM之内存结构详解》中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试者,如果知晓这些变化,又将成为面试中的亮点。
如果在网络上搜索JVM内存结构,90%的可能会搜到Java7及以前的内存图,本篇文章将会对JVM内存结构再次细化,深入理解Java8之后的内部变化。现在意识到关注公众号“程序新视界”的好处了吧。在这里可以不断的刷新你的知识和认知。
JVM内存结构的细化
再来看一下《JVM之内存结构详解》中的内存结构图。

为了更细化的讲解,我们将该图进行进一步的优化调整。针对java7及以前版本的细化。

看出变化了吗?堆和方法区连在了一起,但这并不能说堆和方法区是一起的,它们在逻辑上依旧是分开的。但在物理上来说,它们又是连续的一块内存。也就是说,方法区和前面讲到的Eden和老年代是连续的。

在继续进行下去之前,我们先来理解两个概念:规范和实现。
规范和实现
针对Java虚拟机的实现有专门的《Java虚拟机规范》,在遵守规范的前提下,不同的厂商会对虚拟机进行不同的实现。 就好比开发的过程中定义了接口,具体的接口实现大家可以根据不同的业务需求进行实现。
PS:大家都有必要了解一下《Java虚拟机规范》,关注公众号“程序新视界”,回复“002”获得Java SE 7的虚拟机规范PDF版。
我们通常使用的Java SE都是由Sun JDK和OpenJDK所提供,这也是应用最广泛的版本。而该版本使用的VM就是HotSpot VM。通常情况下,我们所讲的java虚拟机指的就是HotSpot的版本。
永久代(PermGen)
上面理解了规范和实现之后,来看认识一个概念“永久代(Permanet Generation,也称PermGen)”。对于习惯了在HotSpot虚拟机上开发、部署的程序员来说,很多都愿意将方法区称作永久代。
本质上来讲两者并不等价,仅因为Hotspot将GC分代扩展至方法区,或者说使用永久代来实现方法区。在其他虚拟机上是没有永久代的概念的。也就是说方法区是规范,永久代是Hotspot针对该规范进行的实现。
理解上面的概念之后,我们对Java7及以前版本的堆和方法区的构造再进行一下变动。

再重复一遍就是对Java7及以前版本的Hotspot中方法区位于永久代中。同时,永久代和堆是相互隔离的,但它们使用的物理内存是连续的。
永久代的垃圾收集是和老年代捆绑在一起的,因此无论谁满了,都会触发永久代和老年代的垃圾收集。
但在Java7中永久代中存储的部分数据已经开始转移到Java Heap或Native Memory中了。比如,符号引用(Symbols)转移到了Native Memory;字符串常量池(interned strings)转移到了Java Heap;类的静态变量(class statics)转移到了Java Heap。
然后,在Java8中,时代变了,Hotspot取消了永久代。永久代真的成了永久的记忆。永久代的参数-XX:PermSize和-XX:MaxPermSize也随之失效。
元空间(Metaspace)
对于Java8,HotSpots取消了永久代,那么是不是就没有方法区了呢?当然不是,方法区只是一个规范,只不过它的实现变了。
在Java8中,元空间(Metaspace)登上舞台,方法区存在于元空间(Metaspace)。同时,元空间不再与堆连续,而且是存在于本地内存(Native memory)。

本地内存(Native memory),也称为C-Heap,是供JVM自身进程使用的。当Java Heap空间不足时会触发GC,但Native memory空间不够却不会触发GC。
针对Java8的调整,我们再次对内存结构图进行调整。

元空间存在于本地内存,意味着只要本地内存足够,它不会出现像永久代中“java.lang.OutOfMemoryError: PermGen space”这种错误。看上图中的方法区,是不是“膨胀”了。
默认情况下元空间是可以无限使用本地内存的,但为了不让它如此膨胀,JVM同样提供了参数来限制它使用的使用。
- -XX:MetaspaceSize,class metadata的初始空间配额,以bytes为单位,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当的降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize(如果设置了的话),适当的提高该值。
- -XX:MaxMetaspaceSize,可以为class metadata分配的最大空间。默认是没有限制的。
- -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为class metadata分配空间导致的垃圾收集。
- -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为class metadata释放空间导致的垃圾收集。
永久代为什么被替换了
思考一下,为什么使用元空间替换永久代?
表面上看是为了避免OOM异常。因为通常使用PermSize和MaxPermSize设置永久代的大小就决定了永久代的上限,但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。
当使用元空间时,可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制。
更深层的原因还是要合并HotSpot和JRockit的代码,JRockit从来没有所谓的永久代,也不需要开发运维人员设置永久代的大小,但是运行良好。同时也不用担心运行性能问题了,在覆盖到的测试中, 程序启动和运行速度降低不超过1%,但是这点性能损失换来了更大的安全保障。
小结
经过上面的讲解和演变,是不是对JVM的内存结构有了更深的理解了?可以和面试官多聊一会儿了,毕竟面试官的时间也不多了。另外,走过路过不要错过,该系列持续更新中。最后别忘了关注公众号“程序新视界”获得第一手资料。
原文链接:《面试官,Java8 JVM内存结构变了,永久代到元空间》
《面试官》系列文章:
程序新视界:精彩和成长都不容错过

面试官,Java8 JVM内存结构变了,永久代到元空间的更多相关文章
- JAVA8 JVM内存结构变了,永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
- 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...
- JVM 知识点补充——永久代和元空间
之前已经讲过了不少有关 JVM 的内容,今天准备将之前没有细讲的部分进行补充,比如:永久代和元空间. 永久代 Java 的内存中有一块称之为方法区的部分,在 JDK8 之前, Hotspot 虚拟机中 ...
- JVM内存结构从永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
- 面试重灾区——JVM内存结构和GC
JVM介绍 1. JVM的体系架构(内存模型) 绿色的为线程私有,橘色的为线程共有 2. 类加载器 负责将.class文件加载到内存中,并且将该文件中的数据结构转换为方法区中的数据结构,生成一个Cla ...
- 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...
- 2万字长文包教包会 JVM 内存结构 保姆级学习笔记
写这篇的主要原因呢,就是为了能在简历上写个"熟悉JVM底层结构",另一个原因就是能让读我文章的大家也写上这句话,真是个助人为乐的帅小伙....嗯,不单单只是面向面试学习哈,更重要的 ...
- JVM学习十二 - (复习)JVM内存结构
JVM 内存结构 Java 虚拟机的内存空间分为 5 个部分: 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代.元 ...
- JVM——内存结构
一.程序计数器/PC寄存器 (Program Counter Registe) 用于保存当前正在执行的程序的内存地址(下一条jvm指令的执行地址),由于Java是支持多线程执行的,所以程序执行的轨迹不 ...
随机推荐
- 《程序实现》从xml、txt文件里读取数据写入excel表格
直接上码 import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java ...
- charles 访问控制设置
本文参考:charles 访问控制设置 charles 访问控制设置 access control settings 访问账户设置: 这里可以配置连接到charles时的一些配置: 这个访问控制确定谁 ...
- Hadoop 之 Hadoop2.0
1.Hadoop2.0与1.0 答:Hadoop2.0之后的版本移除了原有的JobTracker和TaskTracker,改由Yarn平台的ResourceManager负责集群中所有资源的管理和分配 ...
- airflow的安装
1.环境准备1.1 安装环境1.2 创建用户2.安装airflow2.1 安装python2.2 安装pip2.3 安装数据库2.4 安装airflow2.4.1 安装主模块2.4.2 安装数据库模块 ...
- docker部署jenkins
步骤一: 查找jenkins镜像(也可以直接去jenkins官网找镜像docker pull jenkins/jenkins)(官方版本文档https://hub.docker.com/_/jenki ...
- 数位DP 详解
序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分. 以下是数位DP详解,涉及到的例题有: [HDU2089]不要62 [HDU3652]B-n ...
- Maven 梳理-安装配置
项目构建过程包括[清理项目]→[编译项目]→[测试项目]→[生成测试报告]→[打包项目]→[部署项目]这几个步骤,这六个步骤就是一个项目的完整构建过程. 下载后解压 配置环境变量 F:\jtDev ...
- System.exit退出程序
方法源码: /** * Terminates the currently running Java Virtual Machine. The * argument serves as a status ...
- layui-table与layui-rate评分转换成星级的使用
需求:将layui-table中的某一列,例如:评分,从数据库中查找出来之后,进行layui-rate评分转换显示效果,为星星.显示效果如下: 实现代码: 1.layui中引入rate 2.table ...
- idea必备快捷键
ctrl + F: 在当前文件进行文本查找 ctrl + R: 在当前文件进行文本的替换 ctrl + Z: 撤销操作 ctrl + Y:删除光所在的行 或者选中的行 ctrl + D: 复制光标所在 ...