Kevin's blog Kevin's blog
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档

Kevin

你可以迷茫,但不可以虚度
首页
  • AI基础
  • RAG技术
  • 提示词工程
  • Wireshark抓包
  • 常见问题
  • 数据库
  • 代码技巧
  • 浏览器
  • 手册教程
  • 技术应用
  • 流程规范
  • github技巧
  • git笔记
  • vpn笔记
  • 知识概念
  • 学习笔记
  • 环境搭建
  • linux&运维
  • 微服务
  • 经验技巧
  • 实用手册
  • arthas常用
  • spring应用
  • javaAgent技术
  • 网站
友情链接
  • 分类
  • 标签
  • 归档
  • JVM性能调优

    • JVM类的加载机制
    • JVM内存模型
    • JVM对象创建与内存分配机制
    • JVM垃圾收集算法
    • JVM垃圾收集器
    • JVM调优工具以及调优实战
    • 字节码与操作数栈
      • 字节码概念
        • Classfile
        • Class Metadata
        • Class Declaration
        • Constant Pool
        • Methods
        • Attributes
        • SourceFile
      • TypeTest解释
        • 方法声明和描述符
        • 字节码指令
        • 字节码逻辑详解
        • 属性
        • 注解
    • GCLog分析
    • JVM 内存分析工具 MAT及实践
  • 并发编程

  • MySql

  • spring

  • redis

  • zookeeper

  • rabbitMQ

  • 架构

  • 锁

  • 分库分表

  • 学习笔记
  • JVM性能调优
kevin
2024-04-18
目录

字节码与操作数栈

# 字节码概念

# Classfile

markdownCopy code
Classfile /Users/wenkailiu/work/workspaces/jvm-demo/target/classes/com/olight/cloud/jvmModel/ByteCodeInterView.class
1
2
  • Classfile: 显示类文件的路径。

# Class Metadata

markdownCopy code
Last modified Apr 17, 2024; size 1768 bytes
SHA-256 checksum 7d20ce44559d2f0a5ef07187de3d45aaa9b69274a23eb5934d58c05e3b68eb49
Compiled from "ByteCodeInterView.java"
1
2
3
4
  • Last modified: 类文件最后修改日期。
  • size: 文件大小。
  • SHA-256 checksum: 文件的SHA-256校验和,用于验证文件完整性。
  • Compiled from: 源文件名称。

# Class Declaration

markdownCopy code
public class com.olight.cloud.jvmModel.ByteCodeInterView
minor version: 0
major version: 52
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #8                          // com/olight/cloud/jvmModel/ByteCodeInterView
super_class: #9                         // java/lang/Object
interfaces: 0, fields: 0, methods: 4, attributes: 1
1
2
3
4
5
6
7
8
  • minor version 和 major version: 分别表示类文件的次要和主要版本号。
  • flags: 类的访问标志,例如 ACC_PUBLIC 表示公共类,ACC_SUPER 用于允许某些特殊的方法调用指令。
  • this_class: 当前类的常量池索引。
  • super_class: 父类的常量池索引。
  • interfaces, fields, methods, attributes: 接口、字段、方法和属性的数量。

# Constant Pool

markdownCopy code
Constant pool:
#1 = Methodref          #9.#49         // java/lang/Object."<init>":()V
...
1
2
3
4
  • Constant pool: 常量池条目,每个条目都有一个索引。常量池存储了各种常量信息,包括类、接口、字段和方法的符号引用,以及字面量(如字符串常量)。

# Methods

markdownCopy code
public com.olight.cloud.jvmModel.ByteCodeInterView();
...
public void typeTest();
...
public int mathTest();
...
public int inc();
...
1
2
3
4
5
6
7
8
9

每个方法都有详细的信息,包括:

  • descriptor: 方法的描述符,说明方法的参数和返回类型。

  • flags: 方法的访问标志,如 ACC_PUBLIC。

  • Code

    : 方法的字节码指令和其他信息。

    • stack: 最大堆栈深度。
    • locals: 局部变量表大小。
    • args_size: 参数数量。
  • LineNumberTable: 源文件中行号到字节码指令的映射。

  • LocalVariableTable: 局部变量的描述,包括其生命周期内的作用域。

  • StackMapTable: 用于验证和优化字节码执行的类型信息。

# Attributes

markdownCopy code
RuntimeVisibleAnnotations:
...
1
2
3
  • Attributes: 类、字段或方法级别的附加信息,如注解、泛型签名等。

# SourceFile

markdownCopy code
SourceFile: "ByteCodeInterView.java"
1
2
  • SourceFile: 指明这个类文件是从哪个源文件编译来的。

# TypeTest解释

这个 typeTest 方法展示了 Java 中的自动装箱行为和它对 == 操作符的影响。以下是 javap -verbose 命令输出中每个部分的详细解释:

# 方法声明和描述符

markdownCopy code
public void typeTest();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
1
2
3
4
  • descriptor: ()V - 这表示方法没有参数并且返回类型为 void。
  • flags: (0x0001) ACC_PUBLIC - 表示该方法是公开的。

# 字节码指令

这部分列出了该方法的所有 JVM 字节码指令:

  • bipush: 将单字节的常量值(即5至10)推送至栈顶。
  • invokestatic: 调用一个静态方法,这里用于 Integer.valueOf,实现自动装箱。
  • astore: 将栈顶引用类型值存入本地变量。
  • getstatic: 获取指定类的静态字段,并将其值压入栈顶,这里用于获取 System.out。
  • if_acmpne: 比较栈顶两个引用类型数值,当不相等时跳转。
  • iconst_1 和 iconst_0: 分别将int类型的1和0压入栈顶。
  • goto: 无条件跳转。
  • invokevirtual: 调用实例方法,这里用于 PrintStream.println 打印布尔值。

# 字节码逻辑详解


public void typeTest() {
    Integer i1 = 10;  // 自动装箱,调用 Integer.valueOf(10)
    Integer i2 = 10;  // 同上,Java缓存了-128到127之间的Integer对象,因此i1和i2指向相同的对象
    System.out.println(i1 == i2);  // true,因为i1和i2引用相同

    Integer i3 = 128;  // 自动装箱,调用 Integer.valueOf(128)
    Integer i4 = 128;  // 同上,但128不在缓存范围内,因此i3和i4是不同的对象
    System.out.println(i3 == i4);  // false,因为i3和i4引用不同

    Boolean b1 = true;  // 自动装箱,调用 Boolean.valueOf(true)
    Boolean b2 = true;  // 同上,Boolean.valueOf缓存了TRUE和FALSE实例,因此b1和b2是相同的对象
    System.out.println(b1 == b2);  // true

    Double d1 = 1.0;  // 自动装箱,调用 Double.valueOf(1.0)
    Double d2 = 1.0;  // 同上,但Double没有缓存除0以外的值,因此d1和d2是不同的对象
    System.out.println(d1 == d2);  // false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 属性

  • LineNumberTable: 显示源代码行号与字节码指令的对应关系。
  • LocalVariableTable: 显示方法局部变量的范围、槽位索引、名称和描述符。
  • StackMapTable: 提供了足够的信息来验证字节码的类型安全性,记录了特定程序点的局部变量和操作数栈的类型状态。

# 注解

  • RuntimeVisibleAnnotations: 显示方法的运行时可见注解,这里用了 JUnit 的 @Test 注解。

这个方法主要用来演示不同类型的包装类在使用 ==

上次更新: 2024/04/19, 10:50:53
JVM调优工具以及调优实战
GCLog分析

← JVM调优工具以及调优实战 GCLog分析→

最近更新
01
AI是如何学习的
06-05
02
chatGpt提示原则
06-05
03
提示词工程实践指南
06-05
更多文章>
| Copyright © 2022-2025 Kevin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式