• JVM系列-方法调用的原理


    JVM系列-方法调用的原理

    最近重新看了一些JVM方面的笔记和资料,收获颇丰,尤其解决了长久以来心中关于JVM方法管理的一些疑问。下面介绍一下JVM中有关方法调用的知识。

    目的

    方法调用,目的是选择方法正确的执行版本,也就是找到方法的入口地址。

    方法调用指令

    方法调用的字节码指令一共有五种,分别是:

    1. invokestatic:
      • 类方法:static
    2. invokespecial:
      • 方法:实例构造器
      • 私有方法:private
      • 父类中的方法
    3. invokevirtual
      • 虚方法
      • final修饰的方法
    4. invokeinterface
      • 接口方法
    5. invokedynamic
      • 用于动态语言支持

    方法分类

    非虚方法:

    1. 特点:
      • 在类加载时期,有些方法的调用版本已经能够确定,在类加载-解析阶段,把这些方法的符号引用替换为直接引用(即入口地址)。
    2. 包括:
      1. 类方法
      2. 方法
      3. 私有方法
      4. 父类中的方法
      5. final方法

    即由invokestatic、invokespecial指令调用的方法,以及final修饰的方法,属于非虚方法

    虚方法:

    1. 特点:
      • 在类加载时期,无法确定方法最终的调用版本
    2. 包括:
      • 非非虚方法

    即由invokevirtual调用的方法,除了final修饰的之外,都是虚方法

    调用方式

    解析

    1. 定义:对于非虚方法,在类加载的时候已经能确定这些方法的调用版本,在类加载的解析阶段把符号引用替换为直接引用,就是方法的入口地址
    2. 范围:非虚方法

    分派

    静态分派

    1. 定义:在编译期,根据方法涉及的引用类型(包括参数列表的引用类型和方法的调用者的引用类型)来确定方法调用的(初步)版本,并把相应的符号引用放在字节码指令中,这个步骤叫做静态分派
    2. 范围:虚方法、非虚方法
    3. 应用:方法的重载

    动态分派

    1. 定义:在运行时,根据对象的实际类型来确定方法的调用版本,这个步骤叫做动态分派
    2. 范围:虚方法
    3. 应用:方法的重写
    4. 原理:
      1. 方法调用的部分字节码指令:
        1. aload:在调用方法时,总是有该指令将实际类型的对象引用入栈
        2. 加载方法参数
        3. invokevirtual
          1. 先在栈顶取到实际类型的对象引用
          2. 根据方法的符号引用在本类中寻找,找不到的话依次向上在父类中找该方法
      2. 优化实现:在虚拟机中,虚方法表是动态分派的一种优化实现
        1. 虚方法表:
          1. 定义:类信息的一种,在类加载-准备阶段完成初始化,存放在方法区
          2. 特点:
            1. 虚方法表中存储方法的入口地址
            2. 子类中继承但未重写的方法,在子类的虚方法表中存放的入口地址,就是父类的虚方法表中的入口地址,指向父类的实现
            3. 在父子类中,相同符号引用的方法(重写)的方法,其在各自虚方法表中的索引相同
        2. 解释动态分派:
          1. 根据字节码指令的符号引用,找到该方法在父类虚方法表中的索引
          2. 切换到实际类型的虚方法表,通过该索引,找到方法的入口地址

    总结

    主要内容在于方法调用的方式,即如何找到方法的入口地址的过程。

    在这三种方式中,静态分派发生在编译期,解析发生在类加载时,动态分派发生在运行时。针对三者作用对象的不同可知,静态分派是可以和解析或动态分派同时发生的,如类方法依然可以重载,重写的方法也可以重载。但解析和动态分派是不可共存的。

    以上是我的分享,如有疑问或错误,请指出,一起学习。

    参考

    《深入理解Java虚拟机_JVM高级特性与最佳实践-第3版》

    蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也
  • 相关阅读:
    Oracle Core 学习笔记二 Transactions 和 Consistency 说明
    Oracle AUTO_SPACE_ADVISOR_JOB 说明
    Windows 下 ftp 上传文件 脚本
    Oracle 11g 中 Direct path reads 特性 说明
    Linux 使用 wget 下载 Oracle 软件说明
    Oracle 10g read by other session 等待 说明
    Oracle 11g RAC INS06006 Passwordless SSH connectivity not set up between the following node(s) 解决方法
    SecureCRT 工具 上传下载数据 与 ASCII、Xmodem、Ymodem 、Zmodem 说明
    Oracle RAC root.sh 报错 Timed out waiting for the CRS stack to start 解决方法
    Oracle RESETLOGS 和 NORESETLOGS 区别说明
  • 原文地址:https://www.cnblogs.com/liusai/p/13303106.html
Copyright © 2020-2023  润新知