JAVA通过JVM实现跨平台,在不同平台上允许不同的虚拟机执行同样的字节码文件,来实现跨平台,这是java编译后的代码和机器指令交互的地方,理解JVM有助于在日常工作中避免JVM可能出现的压力及异常,并且可以在项目出现瓶颈时定位问题并解决
JVM区域划分
- JVM指令系统
用来指定需要在目标平台上的操作指令
- 操作码 用来执行一条操作的性质
- 操作数 紧随操作码之后,被分为两个以上字节
- JVM寄存器
用来保存CPU中包含的保存系统状态和处理信息的寄存器组,减少虚拟机对堆栈的访问,常用的JVM寄存器有四种
- PC程序计数器,用于记录程序的执行
- optop操作数栈顶指针,用于记录JAVA栈的指针
- frame当前执行环境指针,用于记录JAVA栈的指针
- vars当前执行环境第一个局部变量指针,用于记录JAVA栈的指针
- JVM栈结构
- 局部变量 存储类方法中的局部变量
- 执行环境 上次调用的方法、局部变量指针、操作数栈、栈底指针
- 操作数栈 存储运算所需要的操作数和结果
- JVM碎片回收堆
JVM存储区
方法区 被所有线程共享,存储加载类时读取的类信息,常量,静态变量以及字节码
- JAVA虚拟机栈 每一个线程都会独享一个栈,为虚拟机执行方法进行服务,存储局部变量表、操作数栈、动态链接、方法出口等
- JAVA虚拟机堆 被所有线程共享,在虚拟机启动时创建,用于存放对象实例,可以细分为新生代Young和老年代Old,年轻代可以再次划分为Eden、FromSurvivor和ToSurvivor,默认情况下新生代占堆内存的三分之一,随着JIT编译器和逃逸分析的发展,虚拟机可以更好的进行栈上分配和标量替换,所以并不是所有的对象创建都会分配到Heap了
- 本地方法栈 每一个线程都会独享一个栈,为虚拟机执行Native方法进行服务,存储局部变量表、操作数栈、动态链接、方法出口等
- 程序计数器 每一个线程都会独享一个程序计数器,相互之间不会影响,记录当前字节码的行号指令器
JVM执行程序的过程
- 加载Class文件
- 管理、分配内存
- 进行垃圾回收