JVM入门系列-JVM总览
(原发于知乎, 定期同步至segmentfault, 原文地址:知乎-JVM入门系列-JVM总览)
Java宣称Write Once Run Everywhere,这意味着在一个平台上开发的java程序可以不加修改的运行在其他平台上面。能达成这个功能依赖的就是jvm屏蔽了底层的差异。
当我们编写.java文件之后,编译器会将其编译成同名的.class文件。class文件是一个字节码文件,jvm会加载并且执行它,下方就是整体框图。
(图片来源:wikipedia-Java virtual machine)
如图所示,虚拟机主要可以被分为三块:
类加载系统
运行时数据区
执行引擎
类加载系统Class Loader Subsystem
类加载系统负责验证并且加载.class文件,主要可以划分为三个步骤:
加载(Loading)
链接(Linking)
初始化(Initialization)
加载
类文件在这一块被加载到内存中去。类加载器(class loader)可以划分为Boot Strap class Loader, Extension class Loader, and Application class Loader
Boot Strap class Loader - 加载系统引导类( $JAVA_HOME/jre/lib))
Extension class Loader - 加载拓展类($JAVA_HOME/jre/lib/ext)
Application class Loader - 也被称为User class loader, 负责加载应用层级的类
链接
Verify - 验证字节码是否正确
Prepare - 在这一步分配静态变量并且设置默认值
Resolve - 所有的符号引用都会被替换成指向方法区的原始引用
初始化
这是类加载的最后一步,所有的静态变量都会被赋值。执行顺序是从上到下的,由父类到子类。
运行时数据区 Runtime Data Area
运行时数据区可以划分为5个区域
方法区 - 保存类数据信息,包括成员信息,父类和接口信息,运行时常量池等,jvm共享
堆区 - 保存所有的对象信息,jvm共享
栈区 - 每个线程独有自己的栈,生命周期和线程一致
PC寄存器区 - 储存当前执行指令的地址,如果执行的是是本地方法pc为null
本地方法栈区 - 和栈区一致,只不过存放的是本地方法信息
执行引擎 Execution Engine
执行引擎负责执行代码,执行引擎会依次读取字节码并且按顺序执行。一般来说可以划分为如下几个组件
字节码解释器
字节码解释器(Bytecode Interpreter),就像名字显示的一样,是用来执行字节码。优点是执行开销小,缺点是执行效率较低。
模板解释器
和字节码解释器差不多,不一样的地方在于直接把对应的指令集转成本地代码
JIT编译器
可以针对热点代码优化,执行开销较大,但是能够针对性的优化,效率最高
垃圾收集器
负责回收不再使用的对象,释放和整理内存
Java Native Interface
Java native interface, 简称JNI。暴露了本地方法的接口,使得java可以调用本地方法
Native Method Libraries
本地方法库
参考: