
文章插图
什么是类加载机制?Class文件描述的各种信息,都需要加载到虚拟机后才能运行 。虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制 。
虚拟机和物理机的区别是什么?这两种机器都有代码执行的能力,但是:
- 物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面的 。
- 虚拟机的执行引擎是自己实现的,因此可以自行制定指令集和执行引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式 。
- 局部变量表
- 操作数栈
- 动态连接
- 方法返回地址

文章插图
Java 方法调用什么是方法调用?方法调用唯一的任务是确定被调用方法的版本(调用哪个方法),暂时还不涉及方法内部的具体运行过程 。
Java的方法调用,有什么特殊之处?Class文件的编译过程不包含传统编译的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址 。这使得Java有强大的动态扩展能力,但使Java方法的调用过程变得相对复杂,需要在类加载期间甚至到运行时才能确定目标方法的直接引用 。
Java虚拟机调用字节码指令有哪些?
- invokestatic:调用静态方法
- invokespecial:调用实例构造器方法、私有方法和父类方法
- invokevirtual:调用所有的虚方法
- invokeinterface:调用接口方法
解释执行当主流的虚拟机中都包含了即时编译器后,Class文件中的代码到底会被解释执行还是编译执行,只有虚拟机自己才能准确判断 。
Javac编译器完成了程序代码经过词法分析、语法分析到抽象语法树,再遍历语法树生成线性的字节码指令流的过程 。因为这一动作是在Java虚拟机之外进行的,而解释器在虚拟机的内部,所以Java程序的编译是半独立的实现 。
基于栈的指令集和基于寄存器的指令集什么是基于栈的指令集?Java编译器输出的指令流,里面的指令大部分都是零地址指令,它们依赖操作数栈进行工作 。
计算“1+1=2”,基于栈的指令集是这样的:
iconst_1iconst_1iaddistore_0两条iconst_1指令连续地把两个常量1压入栈中,iadd指令把栈顶的两个值出栈相加,把结果放回栈顶,最后istore_0把栈顶的值放到局部变量表的第0个Slot中 。
什么是基于寄存器的指令集?最典型的是x86的地址指令集,依赖寄存器工作 。计算“1+1=2”,基于寄存器的指令集是这样的:
mov eax, 1add eax, 1mov指令把EAX寄存器的值设为1,然后add指令再把这个值加1,结果就保存在EAX寄存器里 。
基于栈的指令集的优缺点?优点:
- 可移植性好:用户程序不会直接用到这些寄存器,由虚拟机自行决定把一些访问最频繁的数据(程序计数器、栈顶缓存)放到寄存器以获取更好的性能 。
- 代码相对紧凑:字节码中每个字节就对应一条指令
- 编译器实现简单:不需要考虑空间分配问题,所需空间都在栈上操作
经验总结扩展阅读
- JVM学习笔记——类加载和字节码技术篇
- 详解pyautogui模块
- 2022-11-4 VideoPipe可视化视频结构化框架新增功能详解
- 详细了解JVM运行时内存
- 【JVM】关于JVM,你需要掌握这些 | 一文彻底吃透JVM系列
- Istio Ambient Mesh七层服务治理图文详解
- JVM学习笔记——垃圾回收篇
- 详解AQS中的condition源码原理
- JVM学习笔记——内存结构篇
- FHQ Treap 详解
