Java虚拟机|JVM【适合初学者入门】
0. 前言
为什么要有标题0?不要问,问就是程序员数数都是从0开始的。
前段时间正在看《深入理解Java虚拟机》这本书,看完之后颇有感受,这本书写的非常好,我本人也很喜欢周志明老师的风格,真心佩服周老师对虚拟机的理解这么透彻,但从书的标题也可以看得出“深入”二字,如同书名,该书内容确实对新手来说有些晦涩。所以在这里我总结了一篇Java虚拟机的博文,大家可以把它当做阅读这本书的前奏,让自己在心里有一些Java虚拟机的概念,并有一定的理解。如果喜欢的话,可以点个赞和收藏哦!
本文章参考了博主陈树义的JVM专栏,并在已经过博主本人同意的情况下发布这篇文章。
1. 学习JVM的目的
- 深入地理解 Java 这门语言
- 为线上排查问题打下基础
2. 主要的虚拟机
- 虚拟机的始祖:Sun Classic
- 无疾而终:Sun Exact VM
- 武林盟主:Sun HotSpot VM
- 百家争鸣:BEA JRockit / IBM J9 VM
- 武林外传(那些无名虚拟机):Apache Harmony、Google Android Dalvik VM、Mircosoft JVM等等
3. 什么是虚拟机
我们知道不同的操作系统底层的实现是不一样的。因此在一个操作系统上编译的机器码不能在另一个操作系统上被识别。所以和其他语言不同,Java语言不直接编译成与系统有关的机器码,而是编译字节码,再通过不同的系统上提前安装好的Java虚拟机分别解释成机器码。
4. 源代码到机器码的过程
编译器:
-
前端编译器:源代码到字节码,代表:Sun的javac
- 编译器将Java源代码编译成为字节码文件(A.java–>A.class),字节码文件是由16进制数字组成
-
JIT 编译器:从字节码到机器码,代表:HotSpot VM的C1、C2
-
分类
- 使用 Java 解释器解释执行字节码,启动速度快但运行速度慢
- 使用 JIT 编译器(即时编译器)将字节码转化为本地机器代码,启动速度慢但运行速度快
- Client Compiler(C1 编译器)
- Server Compiler(C2 编译器)
-
运行模式
- 混合模式
- C1 和 C2 两种模式混合起来使用(默认方式)
- 如果想单独使用 C1 模式或 C2 模式,使用
-client或-server打开
- 解释模式
- 所有代码都解释执行
- 使用
-Xint参数打开
- 编译模式
- 优先采用编译,但是无法编译时也会解释执行
- 使用
-Xcomp参数打开
- 混合模式
-
-
AOT 编译器:源代码到机器码,代表:GNU Compiler for the Java(GCJ)
对比:
- 编译速度上,解释执行 > AOT 编译器 > JIT 编译器。
- 编译质量上,JIT 编译器 > AOT 编译器 > 解释执行。
5. 字节码文件的结构
字节码文件由以下七个部分组成
- 魔数与Class文件版本
- 常量池
- 访问标志
- 类索引、父类索引、接口索引
- 字段表集合
- 方法表集合
- 属性表集合
字节码文件中的十六进制数字以若干位为单位,分别代表着以上的信息。
具体内容可查看这篇文章:https://www.cnblogs.com/chanshuyi/p/jvm_serial_05_jvm_bytecode_analysis.html
6. Java虚拟机内存结构
-
虚拟机内存结构(官方也叫运行时数据区)
-
公有:所有线程都共享一个,包含公有数据
- Java堆:几乎所有的实例对象
- 年轻代
- Eden区
- From Survivor 0区
- From Survivor 1区
- 老年代
- 年轻代
- 方法区(1.7版本称为永久代(Permanent Space),1.8版本称为元空间(MetaSpace)):每个类的结构信息,例如:运行时常量池、字段和方法数据、构造方法等
- 常量池:常量池其实是存放在方法区中的
- Java堆:几乎所有的实例对象
-
私有:每个线程都有一个,包含私有数据
-
PC寄存器(Program Counter 寄存器):保存线程当前正在执行的方法
- 如果是native方法,保存的值是undefined
- 如果不是native方法,保存的值是Java虚拟机正在执行的字节码指令地址。
-
Java虚拟机栈
- 与线程同时创建,用来存储栈帧,即存储局部变量与一些过程结果的地方。
- 栈帧存储的数据包括:局部变量表、操作数栈。
-
本地方法栈
- Java 虚拟机使用其他语言(例如 C 语言)来实现指令集解释器时,会使用到本地方法栈。
-
-

最低0.47元/天 解锁文章
589

被折叠的 条评论
为什么被折叠?



