JVM内部结构
负责查找并装载Class 文件到内存,最终形成可以被虚拟机直接使用的Java类型。
在类装载器加载class文件到内存的过程中,虚拟机会提取其中的类型信息,并将这些 信息存储到方法区。方法区用于存
储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。由于所有线程都共享方法区,因此它
们对方法区 数据的访问必须被设计为是线程安全的。
存储Java程序创建的类实例。所有线程共享,因此设计程序时也要考虑到多线程访问对象(堆数据)的同步问题。
Java栈是线程私有的。每当启动一个新线程时,Java虚拟机都会为它分配一个 Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。当线程调用java方法时,虚 拟机压入一个新的栈帧到该线程的java栈中。当方法返回时,这个栈帧被从java栈中弹出并抛弃。
一个运行中的Java程序,每当启动一个新线程时,都会为这个新线程创建一个自己的 PC(程序计数器)寄存器。程序计数器的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条 需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。如果线程正在执行的是一个Java方法,这个计数器 记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。
本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行 Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。任何本地方法接口都会使用某种本地方法栈。当线程调用 Java方法时,虚拟机会创建一个新的栈帧并压入Java栈。然而当它调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的Java栈中压入新 的帧,虚拟机只是简单地动态链接并直接调用指定的本地方法。如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。
负责执行字节码。方法的字节码是由Java虚拟机的指令序列构成的。每一条指令包含一 个单字节的操作码,后面跟随0个或多个操作数,执行引擎执行字节码时,首先取得一个操作码,如果操作码有操作数,取得它的操作数。它执行操作码和跟随的操 作数规定的动作,然后再取得下一个操作码。这个执行字节码的过程在线程完成前将一直持续。