基本概述:
Java 虚拟机简称 JVM, 是 JRE 中的一部分, 也是 Java 程序运行的最关键的部分. 完整的 Java 运行流程大致包括编译. java 文件形成. class 文件, 然后根据. class 文件的内容进行一系列的步骤使整个程序运行起来. 其中将. java 文件编译为. class 文件由 Java 编译器完成, 而由. class 文件进而完成整个运行过程则主要是由 JVM 来完成的. 由于所有的编译链接过程都由 JRE 来完成, 所以 Java 具有良好的平台可移植性, 不依赖具体的操作系统.
具体结构及功能:
1,Class Loader:
该子系统主要负责以下三种工作.
一, 读取 (Loading):Class Loader 会首先读取由 Java 编译器传入的. class 文件, 然后生成相对应的二进制数据并将其存入方法区, 这其中生成的数据主要包括类名, 紧邻的父类, 各种修饰符, 变量和方法的信息. 在这之后, JVM 会自动给这个类创建一个类型为 Class 的对象并存入堆中, 这个对象可以被程序员调用, 从而得到这个类中的相关信息 (也就是上面所讲的存入方法区的那些信息). 需要注意的是, 一个类只会具有一个 Class 对象, 也就是说, 就算有无穷个该类的不同对象, 在堆中也只会有一个对应的 Class 对象.
二, 链接 (Linking): 在读取之后, Class Loader 会对. class 文件进行正确性验证, 看看该类是否被正确定义, 同时是否被正确编译. 如果验证成功, 那么 JVM 就会为类中的变量分配内存, 并且初始化内存为默认值.
三, 初始化 (Initialization): 在这一阶段, 所有的静态变量将被正确赋值, 赋值的顺序是按照代码顺序从前往后, 从父类到子类.
而对于 Class Loader 来说, 其实也大致分为三类. 第一类是 Bootstrap Class Loader, 我们可以理解为最基础的 Class Loader, 因为它只会处理那些已经被完全信任的 class, 也就是 Java 的核心类; 第二类是 Extension Class Loader, 它会处理那些被放置在指定的扩展类文件夹中的类; 第三类是 Application Class Loader, 它处理的是外界定义的类. 至于其中的具体不同呢, 在此就不展开叙述了.
2,JVM Memory:
JVM 的内存区是其存放具体数据和对象的主要区域, 总共由以下五部分组成.
一, 方法区 (Method Area): 方法区中主要存取的是 Class 级别的数据, 包括类名, 父类名, 方法名, 变量名和静态变量等等. 每一个 JVM 只有一块方法区, 所以是一个可以被所有类和进程共享的区域.
二, 堆 (Heap Area): 堆中存放着所有对象的信息. 每一个 JVM 也只有一个堆, 意味着堆也是被共享的.
三, 栈 (Stack Area):JVM 会为每一个线程开辟一个栈区, 而每一个栈区中又会分成许多的块 (Block), 每一个块都代表一个方法调用, 方法中的所有本地变量都会存放在栈中相对应的块中. 一旦该线程终止, 那么这个栈就会被 JVM 销毁. 所以栈区是不共享的.
四, PC 计数器 (PC Register): 记录每一个线程当前运行到的代码地址. 显然, 每一个线程都会有一个对应的 PC 计数器, 所以也是不共享的.
五, 本地方法区 (Native Method Area): 每一个线程都会有一个本地方法区, 其主要存放本地方法的相关信息.
3,Execution Engine:
运行引擎负责真正地运行. class 文件, 它会一行一行地读取. class 中的二进制信息, 然后利用 JVM Memory 中的数据一条一条地执行. 垃圾回收器也是在这个引擎中, 它可以自动检测不再可能被引用的已分配内存并将其回收.
JVM 的大致运行过程到这里就告一段落了. 当然, 还有许许多多的细节在这里没有列出, 如果有需要, 查阅官方文档是最好的办法.
来源: https://www.cnblogs.com/cauchymars/p/10497804.html