jvm核心技术---基础知识(1)

1 java字节码

1.1 什么是字节码

java bytecode由单字节(byte)的指令组成,最多支持256个操作码,只使用了200左右的操作码,还有一些操作码保留给调试操作。
根据指令的性质,分为四大类:
1.栈操作指令,包括与局部变量交互的指令
2.程序流程控制指令
3.对象操作指令,包括方法调用指令
4.算术运算以及类型转换指令

package demo.jvm0104;

class HelloByteCode {
    public static void main(String[] args) {
        HelloByteCode obj = new HelloByteCode();
    }
}

编译

javac demo/jvm0104/HelloByteCode.java

查看字节码

$ javap -c demo.jvm0104.HelloByteCode
Compiled from "HelloByteCode.java"
class demo.jvm0104.HelloByteCode {
  demo.jvm0104.HelloByteCode();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class demo/jvm0104/HelloByteCode
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: return
}

查看字节码详细信息

javap -c -verbose demo.jvm0104.HelloByteCode
$ javap -c -verbose demo.jvm0104.HelloByteCode
Classfile /D:/liyuan-gitee/geekbamg-java-my-vscode/myproj/week01/demo/jvm0104/HelloByteCode.class
  Last modified 2024-7-30; size 301 bytes
  MD5 checksum 07e48d4e5c691a90c0605b12408b37f1
  Compiled from "HelloByteCode.java"
class demo.jvm0104.HelloByteCode
  minor version: 0
  major version: 52
  flags: ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#13         // java/lang/Object."<init>":()V
   #2 = Class              #14            // demo/jvm0104/HelloByteCode
   #3 = Methodref          #2.#13         // demo/jvm0104/HelloByteCode."<init>":()V
   #4 = Class              #15            // java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Utf8               LineNumberTable
   #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               SourceFile
  #12 = Utf8               HelloByteCode.java
  #13 = NameAndType        #5:#6          // "<init>":()V
  #14 = Utf8               demo/jvm0104/HelloByteCode
  #15 = Utf8               java/lang/Object
{
  demo.jvm0104.HelloByteCode();
    descriptor: ()V
    flags:
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #2                  // class demo/jvm0104/HelloByteCode
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 8
}
SourceFile: "HelloByteCode.java"

1.2 方法调用的指令
方法调用的指令:
invokestatic,顾名思义,这个指令用于调用某个类的静态方法,这是方法调用指令中最快的一个。
invokespecial, 用来调用构造函数,但也可以用于调用同一个类中的 private 方法, 以及可见的超类方法。
invokevirtual,如果是具体类型的目标对象,invokevirtual 用于调用公共,受保护和package 级的私有方法。
invokeinterface,当通过接口引用来调用方法时,将会编译为 invokeinterface 指令。
invokedynamic,JDK7 新增加的指令,是实现“动态类型语言”(Dynamically Typed Language)支持而进行的升级改进,同时也是 JDK8 以后支持 lambda 表达式的实现基础。

2 jvm类加载器

2.1 类的生命周期

  1. 加载(Loading):找 Class 文件
  2. 验证(Verification):验证格式、依赖
  3. 准备(Preparation):静态字段、方法表
  4. 解析(Resolution):符号解析为引用
  5. 初始化(Initialization):构造器、静态变量赋值、静态代码块
  6. 使用(Using)
  7. 卸载(Unloading)

2.2 类的加载时机

  1. 当虚拟机启动时,初始化用户指定的主类,就是启动执行的 main 方法所在的类;
  2. 当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类,就是 new一个类的时候要初始化;
  3. 当遇到调用静态方法的指令时,初始化该静态方法所在的类;
  4. 当遇到访问静态字段的指令时,初始化该静态字段所在的类;
  5. 子类的初始化会触发父类的初始化;
  6. 如果一个接口定义了 default 方法,那么直接实现或
  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ly21st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值