当你说“Java虚拟机”时,可能指的是以下三种不同的东西:
- 抽象规范。
- 一个具体的实现。(它或者完全用软件实现,或者以硬件和软件相结合的方式来实现)
- 一个运行中的虚拟机实例。(比如说,在Android系统中运行一个Java程序会启动Dalvik,Linux内核会创建一个Dalvik进程,然后Java程序就运行在这个Dalvik实例中)
0 Java虚拟机的主要任务是装载class文件并且执行其中的字节码。
1 一个运行时的Java虚拟机实例的天职是:负责运行一个Java程序。当启动一个Java程序时,一个虚拟机实例也诞生了。
2 Java虚拟机内部有两种线程:守护线程与非守护线程。守护线程通常是由虚拟机自己使用的,如垃圾回收的线程。
3 每个Java虚拟机都有一个执行引擎,它负责执行那些包含在被装载类的方法中的指令。
“执行引擎”这个术语也可以有三种理解:
- 抽象的规范:使用指令集规定执行引擎的行为。
- 具体的实现:软、硬或多种技术的集合。
- 正在运行的实例:线程。
4 Java虚拟机的运行时数据区包括:方法区,堆,Java栈,PC寄存器和本地方法栈。
5 每个Java虚拟机都有一个方法区和一个堆,它们由该虚拟机实例中所有线程共享。(Java虚拟机规范定义了线程模型,这个模型的目标是要有助于在很多体系结构上都实现它,它和具体的操作系统之间或许存在映射关系)
6 当虚拟机装载一个class文件时,它会从这个二进制文件中解析类型信息,这些信息保存在方法区中。
7 方法区存放的类型信息有:
1)该类型的基本信息,如全限定名(包括其父类),类类型或接口类型,类型的访问修饰符等。
2)该类型的常量池
3)字段信息
4)方法信息
5)除了常量以外的所有类(静态)变量
6)一个到类CLassLoader的引用
7)一个到Class类的引用
8 每当启动一个新线程时,Java虚拟机都会为其分配一个Java栈。
9 虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。
10 某个线程正在执行的方法称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类 ,当前类的常量池称为当前常量池。
11 每当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新帧,在执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等数据。
12 栈帧由三部分组成:局部变量区,操作数栈和帧数据区。
13 运行中的Java程序的每一个线程都是一个独立的虚拟机执行引擎的实例。它要么在执行字节码,要么在执行本地方法。
14 初始化过程:装载——>连接(验证、准备、解析)——>初始化
15 初始化时机:首次主动使用类或接口。
16 装载阶段,Java虚拟机创建一个表示该类型的java.lang.Class类的实例。(接口类型也会创建其Class类)
17 准备阶段,Java虚拟机为类(静态)变量分配内存,设置默认初始值。
18 初始化阶段,类变量被赋予正确的初始值。在class文件中,所有的类变量初始化语句和类型的静态初始化器(static语句块)都被Java编辑器收集在一起,放到一个特殊的方法<clinit>中。对于类来说,称为类初始化方法;对于接口来说,称为接口初始化方法。
19 一旦一个类被被装载、连接和初始化,它就可以随时使用了。程序可以访问它的静态字段,调用静态方法或者创建它的实例。
20 在class文件中,构造函数被称为<init>