少年帮|JVM内幕:Java虚拟机详解( 五 )
跟任何典型的字节码一样 , 操作数与局部变量、操作数栈、运行时常量池的主要交互如下所示 。
构造器函数包含两个指令 。 首先 , this 变量被压栈到操作数栈 , 然后父类的构造器函数被调用 , 而这个构造器会消费 this , 之后 this 被弹出操作数栈 。
sayHello() 方法更加复杂 , 正如之前解释的那样 , 因为它需要用运行时常量池中的指向符号引用的真实引用 。 第一个操作码 getstatic 从System类中将out静态变量压到操作数栈 。 下一个操作码 ldc 把字符串 “Hello” 压栈到操作数栈 。 最后 invokevirtual 操作符会调用 System.out 变量的 println 方法 , 从操作数栈作弹出”Hello” 变量作为 println 的一个参数 , 并在当前线程开辟一个新栈帧 。
类加载器JVM 启动时会用 bootstrap 类加载器加载一个初始化类 , 然后这个类会在public static void main(String[])调用之前完成链接和初始化 。 执行这个方法会执行加载、链接、初始化需要的额外类和接口 。
加载(Loading)是这样一个过程 , 找到代表这个类的 class 文件或根据特定的名字找到接口类型 , 然后读取到一个字节数组中 。 接着 , 这些字节会被解析检验它们是否代表一个 Class 对象并包含正确的 major、minor 版本信息 。 直接父类的类和接口也会被加载进来 。 这些操作一旦完成 , 类或者接口对象就从二进制表示中创建出来了 。
链接(Linking)是校验类或接口并准备类型和父类父接口的过程 。 链接过程包含三步:校验(verifying)、准备(preparing)、部分解析(optionally resolving) 。
校验会确认类或者接口表示是否结构正确 , 以及是否遵循 Java 语言和 JVM 的语义要求 , 比如会进行下面的检查:
- 格式一致且格式化正确的符号表
- final 方法和类没有被重载
- 方法遵循访问控制关键词
- 方法参数的数量、类型正确
- 字节码没有不当的操作栈数据
- 变量在读取之前被初始化过
- 变量值的类型正确
准备过程包括为静态存储和 JVM 使用的数据结构(比如方法表)分配内存空间 。 静态变量创建并初始化为默认值 , 但是初始化代码不在这个阶段执行 , 因为这是初始化过程的一部分 。
解析是可选的阶段 。 它包括通过加载引用的类和接口来检查这些符号引用是否正确 。 如果不是发生在这个阶段 , 符号引用的解析要等到字节码指令使用这个引用的时候才会进行 。
类或者接口初始化由类或接口初始化方法
JVM 中有多个类加载器 , 分饰不同的角色 。 每个类加载器由它的父加载器加载 。 bootstrap 加载器除外 , 它是所有最顶层的类加载器 。
- Bootstrap 加载器一般由本地代码实现 , 因为它在 JVM 加载以后的早期阶段就被初始化了 。 bootstrap 加载器负责载入基础的 Java API , 比如包含 rt.jar 。 它只加载拥有较高信任级别的启动路径下找到的类 , 因此跳过了很多普通类需要做的校验工作 。
- Extension 加载器
- 金戈鐵馬|特朗普力挺铁杆支持者,枪杀两人的少年没错?抗议活动不断发酵
- 少年|央视要搞选秀,热搜沸了!网友提名他当导师,点赞数第一
- 暖夏少年|2020电脑硬盘销量排行榜:七彩虹加入战局,硬是打倒了金士顿
- 少年一梦|2020畅销手机排行,iPhone无人超越,安卓旗舰全线溃败
- 少年帮|进入倒计时,华为突然宣布,供应链将迎来“洗牌”?
- 上线|原创央视也搞成团选秀!《上线吧!华彩少年》有哪些优势?粉丝放心了
- 海报|央视首档少年成团选秀节目《上线吧!华彩少年》开始全球招募
- 少年帮|正式确认?中科院宣布决定,纯国产“龙芯”即将来临
- 光一样的少年|面对后起之秀,苏泊尔不玩价格战,以一抵八多功能破壁机倍受追捧
- 中国新闻网|专家澄清:视觉训练不能治疗青少年真性近视