JVM
帮助指令代码(字节码)与底层进行(操作系统平台和执行指令并管理资源的硬件体系结构)交互。对于字节码来说,它能够模拟机器的寄存器、堆栈等等,它是“一个真实机器有效、独立的复制品。
jvm- 输入:类文件格式的文件,即 *.class文件
- 输出:底层平台可以执行的最终指令,如,二进制文件
- JDK、JRE:JRE是我们安装运行Java程序的最基本软件。它和Java类库以及运行Java程序所需要的其他组件一起够成了JVM的一个实现。JDK(Java开发工具)是JRE的超集。
类加载器
每一个在JRE上运行的Java程序都会创建一个JVM实例。编译后的Java类文件和其他被依赖的类文件会被加载到运行环境中。这一步由类加载器协助完成。
类加载器当运行一个JVM示例时,系统将分配给它一块内存区域(这块内存区域的大小可以设置的),这一内存区域由JVM自己来管理。
runtime data areas
分出来的这一块就称为运行数据区域。运行数据区域可以划分为6大块:Java栈、程序计数寄存器(PC寄存器)、本地方法栈(Native Method Stack)、Java堆、方法区域、运行常量池(Runtime Constant Pool)。前面3各区域(PC寄存器、Java栈、本地方法栈)是每个线程独自拥有的,后三者则是整个JVM实例中的所有线程共有的。
- PC计数器:每一个线程都拥有一个PC计数器,当线程启动(start)时,PC计数器被创建,这个计数器存放当前正在被执行的字节码指令(JVM指令)的地址。
- Java栈:同样的,Java栈也是每个线程单独拥有,线程启动时创建。这个栈中存放着一系列的栈帧(Stack Frame),JVM只能进行压入(Push)和弹出(Pop)栈帧这两种操作。每当调用一个方法时,JVM就往栈里压入一个栈帧,方法结束返回时弹出栈帧。基本类型的实例int a 等在这里,int[] a在这里的指向堆实例的引用。
每个栈帧包含三个部分:本地变量数组,操作数栈,方法所属类的常量池引用。
方法调用时的stack
-
本地方法栈:当程序通过JNI(Java Native Interface)调用本地方法(如C或者C++代码)时,就根据本地方法的语言类型建立相应的栈。
本地方法栈 - 方法区域:方法区域是一个JVM实例中的所有线程共享的,当启动一个JVM实例时,方法区域被创建。它用于存运行放常量池、有关域和方法的信息、静态变量、类和方法的字节码。
-
运行常量池:这个区域存放类和接口的常量,除此之外,它还存放方法和域的所有引用。当一个方法或者域被引用的时候,JVM就通过运行常量池中的这些引用来查找方法和域在内存中的的实际地址。
方法区域和运行常量池 - 堆:堆中存放的是程序创建的对象或者实例。这个区域对JVM的性能影响很大。垃圾回收机制处理的正是这一块内存区域。
执行引擎
类加载器将字节码载入内存之后,执行引擎以Java 字节码指令为单元,读取Java字节码。将字节码转化成平台相关的机器码。这个过程可以由解释器来执行,也可以由即时编译器(JIT Compiler)来完成。
JIT
网友评论