【jvm】虚拟机栈之动态链接

目录

一、说明
  • 1.指向运行时常量池的方法引用
  • 2.每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用
  • 3.包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)
  • 4.在java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的
  • 5.动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用
二、代码示例
package com.learning.stack.dynamic_linking;

/**
 * @Author wangyouhui
 * @Description 动态链接
 **/
public class DynamicLinkingTest {
    int num = 10;

    public void methodOne(){
        System.out.println("方法1执行了");
        methodTwo();
        num++;
    }

    public void methodTwo(){
        System.out.println("方法2执行了");
    }
}
三、生成的字节码
Classfile /F:/jdk-learning/jvm/target/classes/com/learning/stack/dynamic_linking/DynamicLinkingTest.class
  Last modified 2023-10-28; size 756 bytes
  MD5 checksum 96b3029ecd8f2d56b0fc46825936f83b
  Compiled from "DynamicLinkingTest.java"
public class com.learning.stack.dynamic_linking.DynamicLinkingTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #9.#23         // java/lang/Object."<init>":()V
   #2 = Fieldref           #8.#24         // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I
   #3 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = String             #27            // 方法1执行了
   #5 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #6 = Methodref          #8.#30         // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V
   #7 = String             #31            // 方法2执行了
   #8 = Class              #32            // com/learning/stack/dynamic_linking/DynamicLinkingTest
   #9 = Class              #33            // java/lang/Object
  #10 = Utf8               num
  #11 = Utf8               I
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
  #19 = Utf8               methodOne
  #20 = Utf8               methodTwo
  #21 = Utf8               SourceFile
  #22 = Utf8               DynamicLinkingTest.java
  #23 = NameAndType        #12:#13        // "<init>":()V
  #24 = NameAndType        #10:#11        // num:I
  #25 = Class              #34            // java/lang/System
  #26 = NameAndType        #35:#36        // out:Ljava/io/PrintStream;
  #27 = Utf8               方法1执行了
  #28 = Class              #37            // java/io/PrintStream
  #29 = NameAndType        #38:#39        // println:(Ljava/lang/String;)V
  #30 = NameAndType        #20:#13        // methodTwo:()V
  #31 = Utf8               方法2执行了
  #32 = Utf8               com/learning/stack/dynamic_linking/DynamicLinkingTest
  #33 = Utf8               java/lang/Object
  #34 = Utf8               java/lang/System
  #35 = Utf8               out
  #36 = Utf8               Ljava/io/PrintStream;
  #37 = Utf8               java/io/PrintStream
  #38 = Utf8               println
  #39 = Utf8               (Ljava/lang/String;)V
{
  int num;
    descriptor: I
    flags:

  public com.learning.stack.dynamic_linking.DynamicLinkingTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 7: 0
        line 8: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;

  public void methodOne();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #4                  // String 方法1执行了
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: aload_0
         9: invokevirtual #6                  // Method methodTwo:()V
        12: aload_0
        13: dup
        14: getfield      #2                  // Field num:I
        17: iconst_1
        18: iadd
        19: putfield      #2                  // Field num:I
        22: return
      LineNumberTable:
        line 11: 0
        line 12: 8
        line 13: 12
        line 14: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      23     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;

  public void methodTwo();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #7                  // String 方法2执行了
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 17: 0
        line 18: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
}
SourceFile: "DynamicLinkingTest.java"
四、字节码说明
4.1 常量池
Constant pool:
   #1 = Methodref          #9.#23         // java/lang/Object."<init>":()V
   #2 = Fieldref           #8.#24         // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I
   #3 = Fieldref           #25.#26        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = String             #27            // 方法1执行了
   #5 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #6 = Methodref          #8.#30         // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V
   #7 = String             #31            // 方法2执行了
   #8 = Class              #32            // com/learning/stack/dynamic_linking/DynamicLinkingTest
   #9 = Class              #33            // java/lang/Object
  #10 = Utf8               num
  #11 = Utf8               I
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/learning/stack/dynamic_linking/DynamicLinkingTest;
  #19 = Utf8               methodOne
  #20 = Utf8               methodTwo
  #21 = Utf8               SourceFile
  #22 = Utf8               DynamicLinkingTest.java
  #23 = NameAndType        #12:#13        // "<init>":()V
  #24 = NameAndType        #10:#11        // num:I
  #25 = Class              #34            // java/lang/System
  #26 = NameAndType        #35:#36        // out:Ljava/io/PrintStream;
  #27 = Utf8               方法1执行了
  #28 = Class              #37            // java/io/PrintStream
  #29 = NameAndType        #38:#39        // println:(Ljava/lang/String;)V
  #30 = NameAndType        #20:#13        // methodTwo:()V
  #31 = Utf8               方法2执行了
  #32 = Utf8               com/learning/stack/dynamic_linking/DynamicLinkingTest
  #33 = Utf8               java/lang/Object
  #34 = Utf8               java/lang/System
  #35 = Utf8               out
  #36 = Utf8               Ljava/io/PrintStream;
  #37 = Utf8               java/io/PrintStream
  #38 = Utf8               println
  #39 = Utf8               (Ljava/lang/String;)V
4.1 方法调用
  • 1.methodOne方法调用methodTwo方法

    9: invokevirtual #6 // Method methodTwo:()V

  • 2.invokevirtual调用虚方法

    1. #6表示Methodref方法引用,指向#8.#30

      #6 = Methodref #8.#30 // com/learning/stack/dynamic_linking/DynamicLinkingTest.methodTwo:()V

    1. #8表示Class

      #8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest

      #32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #30表示名字和返回类型

      #30 = NameAndType #20:#13 // methodTwo:()V

    1. #20表示名字为methodTwo

      #20 = Utf8 methodTwo

    1. #13表示返回类型为void

      #13 = Utf8 ()V

4.3 变量
    1. int num = 10;

    #2 = Fieldref #8.#24 // com/learning/stack/dynamic_linking/DynamicLinkingTest.num:I

    1. 属性引用,指向#8.#24
    1. #8表示Class

      #8 = Class #32 // com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #32表示类为com/learning/stack/dynamic_linking/DynamicLinkingTest

      #32 = Utf8 com/learning/stack/dynamic_linking/DynamicLinkingTest

    1. #24表示名字和类型

      #24 = NameAndType #10:#11 // num:I

    1. #10表示属性名字为num

      #10 = Utf8 num

    1. #11表示属性的类型int

      #11 = Utf8 I

4.4 字符串
    1. #4表示是字符串

      #4 = String #27 // 方法1执行了

    1. #27表示Utf8的字符串"方法1执行了"

      #27 = Utf8 方法1执行了

4.5 父类Object
    1. #1表示方法引用

      #1 = Methodref #9.#23 // java/lang/Object."<init>":()V

    1. #9表示类

      #9 = Class #33 // java/lang/Object

    1. #33表示类名为java/lang/Object

      #33 = Utf8 java/lang/Object

4.6 System类
    1. #3表示属性引用

      #3 = Fieldref #25.#26 // java/lang/System.out:Ljava/io/PrintStream;

    1. #25表示类

      #25 = Class #34 // java/lang/System

    1. #34表示类名为java/lang/System

      #34 = Utf8 java/lang/System

    1. #26表示名称和类型

      #26 = NameAndType #35:#36 // out:Ljava/io/PrintStream;

    1. #35表示名称为out

      #35 = Utf8 out

    1. #36表示类型为 Ljava/io/PrintStream

      #36 = Utf8 Ljava/io/PrintStream;

相关推荐
pjx9872 小时前
JVM 语言与生态
jvm
猿究院---王某人2 小时前
Java 内存模型(JMM)
java·开发语言·jvm
爱棋笑谦6 小时前
JVM基础
jvm
懒洋洋大魔王16 小时前
7.Java高级编程 多线程
java·开发语言·jvm
只吹45°风16 小时前
JVM-类加载器的双亲委派模型详解
jvm·类加载器·双亲委派
五味香19 小时前
C++学习,动态内存
java·c语言·开发语言·jvm·c++·学习·算法
longlongqin21 小时前
JVM 虚拟机的编译器、类加载过程、类加载器有哪些?
jvm
niceffking21 小时前
JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位
java·jvm
刘大猫.1 天前
Arthas dashboard(当前系统的实时数据面板)
jvm·arthas·dashboard·当前系统的实时数据面板·dashboard命令·arthas命令
longlongqin1 天前
JVM 内存结构?
jvm