JVM介绍(针对JDK8+)
JVM介绍(针对JDK8+)
之前整理过一篇jdk7以前版本的jvm,然后有朋友建议更新一下。实在不好意思,本人比较懒,好多东西只是记录在本地会更新到网上,今天咱们先简单聊一下jdk8+后jvm的的变动信息
关系图如下
有图可知,一个java文件首先由java编译器编译为class文件,在由类加载器加载到运行时数据区内,(类加载器和运行时数据区都属于jvm的概念,面试时不要丢掉任何一部分哦)。
运行时数据区
JVM栈 (Java Virtual Machine Stacks)
每当启动一个新线程的时候,java虚拟机都会为它分配一个java栈。java以栈帧为单位保存线程的运行状态。虚拟机只会对java栈执行两种操作:以栈帧为单位的压栈或者出栈。
一个栈帧包含:局部变量、操作数栈、动态链接、方法出口等信息
堆内存 (Heap Memory)
存储的是对象实例和数组,每个对象包含一个与之对应的class信息–class的目的是得到操作指令。
jvm只有一个堆区(heap)被所有线程共享
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。
方法区(元空间) (Metaspace)
jdk8+以后,JVM 将移除永久区,使用本地内存来存储类元数据信息并称之为:元空间(Metaspace)
元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存
元空间中存储的数据:常量、8大基本数据类型、静态变量(static、final)、类信息(字节码信息)、即时编译器编译后的代码
本地方法栈 (Native Method Stacks)
和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。
Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。一个不支持本地方法执行的JVM没有必要实现这个数据区域。本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误。
在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。
程序计数器 (Program Counter (PC) Register)
用于保存当前线程执行的内存地址。
由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。
先简单介绍到这里,后期会补充类加载的相关信息,上面描述如有问题,欢迎伙伴们提示