前言
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上一次编译,多次运行,具有跨平台性。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
正文
Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法区。
-
JVM是什么
JVM,JRE,JDK 都是 java 语言的支柱,他们分工协作。但不同的是 Jdk 和 JRE 是真实存在的,而 JVM 是一个抽象的概念,并不真实存在。JVM是一种用于计算设备的规范,它是一个虚构的计算机的软件实现,简单的说,JVM是运行byte code字节码程序的一个容器。
-
JVM的特点
-
基于堆栈的虚拟机:最流行的计算机体系结构,如英特尔 X86 架构和 ARM 架构上运行基于 寄存器。比如,安卓的 Davilk 虚拟机就是基于 寄存器 结构,而 JVM 是基于栈结构的。
-
符号引用 :除了基本类型以外的数据 (类和接口) 都是通过符号来引用,而不是通过显式地使用内存地址来引用。
-
垃圾收集 :一个类的实例是由用户程序创建和垃圾回收自动销毁。
-
网络字节顺序 :Java class文件用网络字节码顺序来进行存储,保证了小端的Intel
x86架构和大端的RISC系列的架构之间的无关性。
-
-
JVM字节码
- JVM使用Java字节码的方式,作为Java 用户语言 和 机器语言 之间的中间语言。实现一个通用的、 机器无关 的执行平台。
-
JVM能干什么?
- 基于安全方面考虑,JVM 要求在 class 文件中使用强制性的语法和约束,但任意一门语言都可以转换为被 JVM 接受的有效的 class 文件。作为一个通用的、机器无关的执行平台,任何其他语言的实现者都可将 JVM 当作他的语言产品交付媒介。
-
JVM 中执行过程如下:
-
加载代码
-
验证代码
-
执行代码
-
提供运行环境
-
-
JVM生命周期?
- 启动:任何一个拥有main方法的class都可以作为JVM实例运行的起点。
- 运行:main函数为起点,程序中的其他线程均有它启动,包括daemon守护线程和non-daemon普通线程。daemon是JVM自己使用的线程比如GC线程,main方法的初始线程是non-daemon。
- 消亡:所有线程终止时,JVM实例结束生命。
-
JVM组成架构?
Java虚拟机主要分为以下五个区:
一、方法区(METHOD AREA):
-
有时候也成为永久代,在该区内很少发生垃圾回收,但是并不代表不发生GC,在这里进行的GC主要是对方法区里的常量池和对类型的卸载
-
方法区主要用来存储已被虚拟机加载的类的信息、常量、静态变量和即时编译器编译后的代码等数据。
-
该区域是被线程共享的。
-
方法区里有一个运行时常量池,用于存放静态编译产生的字面量和符号引用。该常量池具有动态性,也就是说常量并不一定是编译时确定,运行时生成的常量也会存在这个常量池中。
-
个人理解的方法区就是封装了一个java class 的所有信息
二、堆 (HEAP)
java堆是所有线程所共享的一块内存,在虚拟机启动时创建,几乎所有的对象实例都在这里创建,因此该区域经常发生垃圾回收操作。
三、虚拟机栈(JAVA STACK):
- 虚拟机栈也就是我们平常所称的栈内存,它为java方法服务,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接和方法出口等信息。
- 虚拟机栈是线程私有的,它的生命周期与线程相同。
- 局部变量表里存储的是基本数据类型、returnAddress类型(指向一条字节码指令的地址)和对象引用,这个对象引用有可能是指向对象起始地址的一个指针,也有可能是代表对象的句柄或者与对象相关联的位置。局部变量所需的内存空间在编译器间确定
- 操作数栈的作用主要用来存储运算结果以及运算的操作数,它不同于局部变量表通过索引来访问,而是压栈和出栈的方式
- 每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接.动态链接就是将常量池中的符号引用在运行期转化为直接引用。
四、本地方法区 (NATIVE METHOD STACK)
本地方法区和虚拟机栈类似,只不过本地方法栈为Native方法(对非java语言调用的接口)服务。
五、程序计数器 (PEOGRAM COUNTER REGISTER)
内存空间小,字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数器完成。该内存区域是唯一一个java虚拟机规范没有规定任何OOM情况的区域。