GitHub 标星 8k!Java 虚拟机 5 大核心知识点
1.1 基于栈(Stack-based): 不同于 Intel x86 和 ARM 等比较流行的计算机处理器都是基于寄存器(register)架构,JVM 是基于栈执行的。
1.2 符号引用(Symbolic reference): 编译后的.class 文件中,除基本类型外的所有 Java 类型都是通过符号引用取得关联的,而非显式的基于内存地址的引用。
【符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量。例如,在 Class 文件中它以 CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info 等类型的常量出现。
在编译时,java 类还没有被加载到内存中,所以并不知道所引用的类的实际地址,因此只能使用符号引用来代替;在解析阶段,Java 虚拟机会把类的二进制数据中的符号引用替换为直接引用(指向内存地址)】
1.3 垃圾回收机制: 类的实例通过用户代码进行显式创建,但却通过垃圾回收机制自动销毁。
1.4 通过明确清晰基本类型确保平台无关性: 像 C/C++等传统编程语言对于 int 类型数据在同平台上会有不同的字节长度。JVM 却通过明确的定义基本类型的字节长度来维持代码的平台兼容性,从而做到平台无关。
1.5 网络字节序(Network byte order): 是 TCP/IP 中规定好的一种数据表示格式。Java class 文件的二进制表示使用的是网络字节序,即基于 big endian 的字节序。
【字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。?Little endian:将低序字节存储在起始地址;?Big endian:将高序字节存储在起始地址】
2、Java 字节码在 JVM 中的运行
=================
2.1 编译机制
Java 字节码无法直接直接,需要 JVM 将其翻译成机器码。
在 HotSpot 里面,翻译过程有两种形式:第一种是解释执行,相当于同声传译,即每解析一条字节码,便翻译成机器码并执行;第二种是即时编译(Just-In-Time compilation,JIT),则相当于线下翻译,即将整个方法中所包含的字节码统一翻译成机器码后在执行。前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。
HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。
2.2 加载流程
执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机的方法区中。实际运行时,执行引擎会执行方法区内的代码。每当调用一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。当退出当前执行的方法时,不管是正常返回还是异常返回,JVM 均会弹出当前栈帧,并将之舍弃。
3、加载 Java 类
=========
JVM 加载 Java 类的过程可分为三大步骤:加载、链接以及初始化。
3.1 加载
指通过类加载器查找字节流,创建类的过程。类加载器使用双亲委派模型,即接收到加载请求时,会先将请求转发给父类加载器。
3.2 链接
指将创建成的类合并至 JVM 中,使之能够执行的过程。
链接还分验证(验证被加载类是否满足 JVM 约束)、准备(为被加载类静态字段分配内存)和解析(将被加载类中的符号引用解析成为实际引用)三个阶段。其中,JVM 规范并不要求解析阶段一定要在链接步骤中完成。
最后
在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例感兴趣的朋友可以点击Java学习免费获取。
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
大家看完有什么不懂的可以在下方留言讨论也可以关注。
觉得文章对你有帮助的话记得关注我点个赞支持一下!
评论