对JVM的整体结构理解
作用
jvm是一个虚拟机,是java进程和操作系统交互的一个中间件,jvm会作为进程获得操作系统给的cpu、内存等资源供调度供给java进程。jvm也是java代码可以做到一次编译到处运行的原因。
内存结构
jvm整体分为类加载、运行时数据区、执行引擎三大部分。
类加载器
类加载是进入jvm的入口,任何类想要被引用都需要通过类加载阶段,它分为加载、验证、准备、解析、初始化五个阶段。加载阶段是将类对应的二进制字节流代表的静态数据结构转为方法区的运行时数据结构,同时会在内存中生成一个Class对象作为访问该类的一个接口,在加载阶段会调用到jvm的外部组件,类加载器。验证阶段则主要是为了保证加载的类的二进制流的合法性,保证运行以后不会对jvm产生危害。准备阶段则是对类变量进行初始化,提供初始内存,但final修饰的类变量会直接赋值,因为final修饰的类变量会在编译阶段就进行初始化,并且其储存的位置也不在方法区,而是常量池。解析阶段则是将符合引用转换为直接引用。初始化阶段的本质是运行类构造器方法clinit(),对类变量进行赋值。
运行时数据区
这个区域则存放运行时进行存储的数据。内部分为堆、虚拟机栈、程序计数器、本地方法栈、方法区。其中hotstop将本地方法机栈和虚拟机栈进行合并。 堆,是存储的主要地方,所有对象的数据结构和数据都会存储在堆空间中。这里是jvmGC的主要地方,同时也是线程共享的。 方法区,在jdk1.8以后也改名为元空间。主要存储类信息,类加载后信息存储在这里,同时还存放大部分的常量池,也是线程共享,但是一般不进行GC。 虚拟机栈,模拟线程运行时的数据结构。它与直接线程相关,每个线程运行时都会开辟一个与之对应的虚拟机栈,虚拟机栈内部是一个个的栈帧,模拟的就是线程运行时的方法栈,虚拟机是线程私有的,同时因为虚拟机主要存储的是数据的引用,占用内存少,所以没有GC。 程序计数器,线程私有,为每个虚拟机栈专门配置,记录程序的运行位置。
执行引擎
类加载是程序数据进入jvm的入口,而运行时数据区则是jvm运行的数据,执行引擎则是发动机,保证代码的运行。执行引擎的本质工作其实还是翻译官的工作,因为class文件的字节流并不能被cpu直接执行,而执行引擎就是将字节流翻译为机器语言。