Java基础篇(JVM)——总领

这篇文章由几个问题组成,目的是想厘清JVM的一些基本概念,同时最后引出JVM知识体系的几大块,以后的文章就围绕这几大块展开。

1. 什么是JVM?它有什么作用?

JVM是Java虚拟机的简写,Java是先编译后解释型的语言,其最初设计的目的是“一次编写,到处运行”,也就是要实现平台的无关性,这个特性正是通过使用JVM实现的。

编译器首先将Java程序编译成字节码.class文件,再由JVM加载,解释成机器指令给不同的系统(从这个意义上说,Java属于解释型语言,因为它并非是直接将代码编译成机器可以理解的二进制文件)。不同系统的JVM是不一样的,但是都能处理.class文件,所以不同运行平台都能处理程序员编写的同一份Java代码。而对于其它传统编程语言来说(如C/C++),由于它和底层密切相关,其基础类型的字节长度是不一样的,导致平台兼容性就差了很多。

2. JVM的特性有哪些?

(1)基于栈的虚拟机:不同于Intel x86和ARM等比较流行的计算机处理器都是基于寄存器[1](register)架构,JVM是基于栈执行的。(通过.class文件反编译(javap -verbose xxx.class)后的字节码文件可以看到,JVM是通过栈将指令逐条压入的)

(2)符号引用:处基本类型以外的所有Java类型都是通过符号引用取得关联的,而非显式的基于内存地址的引用。(类加载机制过程是加载-连接-初始化-使用-卸载,其中,连接分成三步:准备、验证、解析,解析阶段的目的就是将符号引用转变成直接引用)

(3)垃圾回收机制:类的实例由用户显式创建,通过垃圾回收机制进行销毁。

(4)基本类型长度与平台无关。

(5)网络字节序:Java .class文件的二进制表示使用的是基于网络的字节序,即大端(big endian)字节序,保证了各个平台之间的统一性。

(大端字节序:即低位地址存储数据的高位值;小端字节序则相反。

网络字节序是大端字节序,也就是说在网络传输过程中,首先接收到的是数字的高位值。

Intel x86使用小端字节序,RISC[2]系列平台使用了大端字节序)

3. 有哪些类型的JVM?

 最主流的是HotSpot VM,是Sun JDK和open JDK共同使用的VM,由于09年Oracle收购了BEA和Sun,在JDK 1.8之后的HotSpot VM是原来的HotSpot VM和JRockit VM的合并版。

HotSpot VM的优点是可以动态编译[3],大大提升了程序执行的性能。

其它的还有:IBM的J9 VM、Zing VM等。

另外,Android平台上的Dalvik,虽然名义上不叫JVM,但它可以将Java代码转化成Dalvik可以使用的代码,其功能基本和JVM相同,也可以归作JVM。(为此,Oracle还告了Google)

4. 字节码是什么?

 字节码是程序代码到机器码之间的中间代码。JVM并非一次性将所有字节码读入内存,而是在使用时加载(类加载机制);同时也并非将所有的字节码都预先解释成机器码,而是通过JIT技术,仅解释部分热点代码以提高性能。

可以用JDK自带的反编译命令javap -verbose查看字节码,这时可以看到JVM基于栈的设计,对每个指令都是入栈出栈来执行,另外,还可以看到JVM是符号引用,而非指向直接内存地址的引用;也可以用16进制工具winHex查看字节码,这时会看到魔数、版本号、常量池(个数、类型等)等信息。

5. JDK、JRE和JVM的关系是什么?

JDK包含了JRE,还包含开发工具(编译工具javac、反编译工具javap、打包工具jar等);

JRE是Java程序运行环境,包含了JVM,还包含其它的程序运行需要的系统API,如rt.jar等。

JVM是运行Java程序的核心,用来处理字节码、管理内存等。

6. JVM知识体系分哪几部分?

在我这里,将JVM知识体系分成五个部分:

(1)类的加载机制;

(2)JVM内存模型和内存结构;

(3)GC策略/算法;

(4)GC分析、JVM调优;

(5)虚拟机性能监控与故障处理。

先总述一下这几大块的关系:

对于已有的Java程序代码,首先将其编译成字节码,然后需要加载进内存中,这时要用到类的加载机制(包括类如何加载,什么时候加载,什么时候使用与卸载等);加载进内存中需要分配内存空间,所以要了解JVM的内存模型和内存结构;JVM会针对程序进行GC,所以要了解什么时候GC、如何GC等;接下来还会涉及到JVM调优,调优主要针对的是GC,所以调优之前首先要分析GC的运行情况;最后了解HotSpot虚拟机相关的知识以及虚拟机性能监控和故障处理的知识。

以后JVM的文章大致就围绕这几块展开。

注:

[1] 寄存器:是CPU中的部件,读写速度非常快,可用来进行算术和逻辑运算、存储地址(寻址)等

[2] RISC:即精简指令集的简写。RISC是CPU的一种设计模式,它对指令数目和寻址方式做了精简,且所有指令的格式一致,指令周期相同,使得硬件只用执行简单的那部分指令,其它复杂指令则通过简单指令复合而成。它的实现更容易,并行程度更好,编译效率更高。

[3] 动态编译:也可以叫做JIT。Java是先将程序代码编译成字节码,再由虚拟机解释给不同的机器来执行。使用HotSpot VM,虚拟机可以读入字节码之后,不将所有的字节码都逐条解释成机器码存起来,因为这样效率太低,而是将经常重复执行的“热点”代码先解释成机器码,并进行优化。这样可以提高性能。对这个热点代码检测技术,之后在写到HotSpot的时候,会详细写这部分的内容。

原文地址:https://www.cnblogs.com/lilei94/p/9742746.html