11.4java语言执行浅析4

article/2025/6/17 19:24:58

编译成字节码(.class 文件)

使用 javac 命令将源代码编译为 Java 字节码(bytecode) 

它不是机器码,而是 JVM 能理解的中间语言(字节码),具有平台无关性。

编译过程简要:

  1. 词法分析:将字符序列转换为标记(token)。
  2. 语法分析:构建抽象语法树(AST)。
  3. 语义分析:检查类型、变量是否合法。
  4. 生成字节码:将 AST 转换为 .class 文件中的字节码指令。

类加载(Class Loading)

当你运行程序时,JVM 启动并开始加载所需的类:

JVM 使用 类加载器(ClassLoader) 来加载 .class 文件。类加载包括以下步骤:

  • 加载(Loading):查找并导入类的 .class 文件。
  • 验证(Verification):确保字节码是安全且符合规范的。
  • 准备(Preparation):为类变量分配内存,并设置默认初始值。
  • 解析(Resolution)(可选延迟):将符号引用替换为直接引用。
  • 初始化(Initialization):执行类构造器 <clinit> 方法(静态变量赋值和静态代码块)。

执行字节码(Execution Engine)

Java 字节码由 JVM 的执行引擎来执行。具体方式有三种:

1. 解释执行(Interpretation)

JVM 逐条解释字节码并执行,速度较慢但跨平台兼容性强。

2. 即时编译(JIT Compilation)

热点代码(频繁执行的代码)会被 JIT 编译器动态编译为本地机器码,提升性能。

3. 本地方法调用(Native Method)

某些操作(如 I/O、线程)通过调用操作系统原生库实现。


垃圾回收(Garbage Collection)

在程序运行期间,JVM 自动管理内存,GC 会定期回收不再使用的对象,释放内存资源。


程序终止

main() 方法执行完毕,或者遇到异常、系统退出等,JVM 关闭,程序结束。


总结流程图

Java源代码 (.java)↓ 编译 (javac)
字节码文件 (.class)↓ 运行 (java)
类加载 → 验证 → 准备 → 解析 → 初始化↓
执行引擎(解释 + JIT 编译)↓
垃圾回收 & 程序终止

.class 文件整体结构(以字节为单位)

类型数量描述
魔数(magic)u41固定值 0xCAFEBABE,标识这是 Java class 文件
次版本号(minor_version)u21次版本号
主版本号(major_version)u21主版本号,如 52 表示 JDK 8
常量池计数器(constant_pool_count)u21常量池项数量(从 1 开始编号)
常量池(constant_pool)cp_info[]constant_pool_count - 1存储各种常量(字符串、类名、字段名等)
访问标志(access_flags)u21类的访问权限(public、abstract 等)
类索引(this_class)u21当前类的常量池索引
超类索引(super_class)u21父类的常量池索引
接口计数器(interfaces_count)u21实现的接口数量
接口表(interfaces)u2[]interfaces_count接口的常量池索引数组
字段计数器(fields_count)u21字段数量
字段表(fields)field_info[]fields_count字段的详细信息
方法计数器(methods_count)u21方法数量
方法表(methods)method_info[]methods_count方法的详细信息
属性计数器(attributes_count)u21属性数量
属性表(attributes)attribute_info[]attributes_count属性信息(如 SourceFile、Code 等)

各部分详解

1. 魔数(Magic Number)

  • 固定值:0xCAFEBABE
  • 用于识别是否是合法的 class 文件。

2. 版本号(Version)

  • minor_version + major_version
  • 常见主版本号对应:
    • JDK 1.1: 45
    • JDK 1.2: 46
    • ...
    • JDK 8: 52
    • JDK 17: 61

3. 常量池(Constant Pool)

  • 是 .class 文件中最复杂也最重要的结构之一。
  • 包含多种类型的常量,例如:
    • 类名、字段名、方法名
    • 字符串常量
    • 方法引用、字段引用
    • UTF-8 字符串等

常量池中的每一项都有一个 tag 字段表示类型,比如:

  • CONSTANT_Utf8 (1)
  • CONSTANT_Class (7)
  • CONSTANT_Fieldref (9)
  • CONSTANT_Methodref (10)
  • ...

4. 访问标志(Access Flags)

  • 标识该类是 public、final、interface、abstract 等。

5. 类索引、超类索引、接口表

  • 通过常量池索引来引用当前类、父类和实现的接口。

6. 字段表(Fields)

  • 描述类中声明的变量(包括静态变量、实例变量等)。
  • 每个字段包含:
    • 名称索引
    • 描述符索引(描述字段类型)
    • 属性表(如 ConstantValue、Synthetic 等)

7. 方法表(Methods)

  • 描述类中声明的方法。
  • 每个方法包含:
    • 名称索引
    • 描述符索引(参数和返回值类型)
    • 属性表(如 Code、Exceptions、LineNumberTable 等)

方法体(Code 属性)

  • 在方法的属性表中,Code 属性是最核心的部分,它包含:
    • 操作数栈最大深度
    • 局部变量表大小
    • 字节码指令(bytecodes)
    • 异常处理表
    • 其他调试信息(如行号表)

8. 属性表(Attributes)

  • 用于扩展 class 文件的附加信息。
  • 常见属性有:
    • Code:方法的字节码
    • SourceFile:记录源文件名
    • LineNumberTable:源码与字节码的行号映射
    • LocalVariableTable:局部变量表信息
    • Exceptions:方法抛出的异常列表
    • BootstrapMethods:用于动态语言支持(如 Lambda 表达式)

示例解析(简单 Hello.class)

假设我们有如下 Java 源码:

public class Hello {public static void main(String[] args) {System.out.println("Hello World");}
}

编译后生成的 Hello.class 文件结构大致如下:

magic:              CAFE BABE
minor_version:      0
major_version:      52 (JDK 8)
constant_pool:      [各种符号引用]
access_flags:       0x0031 (public final super)
this_class:         #5 => "Hello"
super_class:        #6 => "java/lang/Object"
interfaces:         none
fields:             none
methods:- main: descriptor ([Ljava/lang/String;)V, flags: public staticattributes:- Code:max_stack: 2max_locals: 1code_length: 10code:0: getstatic     #2  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #3  // String Hello World5: invokevirtual #4  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: returnexception_table: emptyattributes: LineNumberTable, LocalVariableTable

 查看 .class 文件内容的工具

你可以使用以下工具来查看 .class 文件的内容:

1. javap 反汇编工具(JDK 自带)

javap -c -verbose Hello.class
  • -c:显示字节码指令
  • -verbose:显示更详细的结构信息(包括常量池、属性等)

2. 二进制编辑器(如 Hex Editor)

  • 可查看原始的十六进制数据。
  • 如:WinHex、HxD、xxd 等。

3. ASM、ByteBuddy、Javassist 等字节码操作库

  • 可用于分析、修改 .class 文件内容,常用于 AOP、性能监控、热修复等高级场景。


http://www.hkcw.cn/article/NLQJHgDMST.shtml

相关文章

Luminar Neo:摄影室灯光

在专业人像摄影中&#xff0c;打光始终是一门核心技术。但对于多数摄影师而言&#xff0c;搭建真正的摄影棚既耗时又昂贵。Luminar Neo 推出的创新工具“摄影室灯光”&#xff08;Studio Light&#xff0c;也称“摄影棚光线”&#xff09;&#xff0c;正是为了解决这一难题而生…

机器学习知识图谱——NN全连接神经网络算法

目录 一、图解全连接神经网络(NN)算法知识图谱 二、什么是全连接神经网络(NN)? 三、网络结构 四、神经元计算公式 五、激活函数常用类型 六、前向传播 + 反向传播 七、训练流程图示 八、优点 九、缺点 十、Python 示例代码 (使用 PyTorch) 十一、应用领域 机…

DFS入门刷题

目录 P1683 入门 P1596 [USACO10OCT] Lake Counting S 1114. 棋盘问题 P1025 [NOIP 2001 提高组] 数的划分 P1683 入门 #include <iostream> using namespace std; char a[30][30]; bool vis[30][30]; int res 1; int n, m; int dx[] {-1, 1, 0, 0}; int dy[] {0,…

如何在 Ubuntu22.04 上安装并开始使用 RabbitMQ

单体架构学的差不多了&#xff0c;可以朝着微服务进军了&#xff0c;笔者打算实操一下 RabbitMQ&#xff08;这个和 Redis 一样重要的组件) 笔者这里采用的是本地 wsl2 的 Ubuntu22.04 先按指定的博客进行前置操作 Ubuntu22.04 安装 RabbitMQ 解决 ARM Ubuntu 22.04 缺少 libs…

歼-10CE火出圈,不愧是猛龙!

歼-10CE火出圈,不愧是猛龙!国产战机霸气名称大盘点在近期举行的马来西亚兰卡威航展上各国顶级装备纷纷亮相在中国展台上近期在实战中一鸣惊人的歼-10CE战斗机模型占据C位人气爆棚观众纷纷前来打卡参观硬核出圈的歼-10也被称为“猛龙”国产歼击机有用猛兽命名的传统小编带你盘…

荣昌政府食堂推出六一套餐 亲子家庭专属福利

端午假期期间,全国多地政府机关食堂面向社会公众开放。例如,重庆市荣昌区政府机关食堂在5月31日中午向游客开放,首日吸引了超过3000名游客前来体验。为了庆祝六一儿童节,该食堂特别推出了61元的家庭套餐,包括荣昌卤鹅、黄凉粉等特色菜品,并新增了粽子和薯条、鸡腿、鸡块等…

樊振东加盟德甲联赛 乒坛巨星开启欧洲冒险

6月1日,FC萨尔布吕肯乒乓球俱乐部宣布奥运冠军樊振东将加盟。樊振东,这位曾经的世界第一、国际乒乓球界的巨星,将在新赛季代表该俱乐部征战德国乒乓球甲级联赛(TTBL)。28岁的中国选手樊振东表示非常期待在萨尔布吕肯和TTBL的新挑战,并渴望成为俱乐部的一员,在新的环境中…

樊振东加盟德国乒乓球甲级联赛 乒坛巨星欧洲冒险

6月1日,FC萨尔布吕肯乒乓球俱乐部宣布奥运冠军樊振东将加盟。这位曾经的世界第一、国际乒乓球界的巨星将在新赛季代表该俱乐部征战德国乒乓球甲级联赛(TTBL)。28岁的中国选手樊振东表示非常期待在萨尔布吕肯和TTBL的新挑战,并渴望成为俱乐部的一员,体验新的环境并帮助球队…

IDM下载器 Internet Download Manager v6.42 Build 39

—————【下 载 地 址】——————— 【​本章下载一】&#xff1a;https://pan.xunlei.com/s/VORWCoLNITytLXc_Obt47jr1A1?pwdipt3# 【​本章下载二】&#xff1a;https://pan.quark.cn/s/d7cd16fee51c 【百款黑科技】&#xff1a;https://ucnygalh6wle.feishu.cn/wiki/…

C++二叉树常见OJ题分析

OJ&#xff08;一&#xff09;&#xff1a;根据二叉树创建字符串 606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 1.&#xff08;ps:接下来的解答来自LeetCode的官方解释&#xff1a;这里只是为了让以后复习便利而已。&#xff09; 如果当前节点有两个孩子…

Spring Boot养老院管理系统源码分享

概述 基于Spring Boot开发的养老院管理系统&#xff0c;该系统通过智能化管理模块&#xff0c;为养老机构提供高效运营解决方案。 主要内容 后台管理功能 系统后台功能完善&#xff0c;左侧导航栏涵盖首页、安全巡查管理、设备管理等模块。设备管理界面以表格形式清晰展示设…

数据库-MySQL索引事务

1 索引 针对查询操作引入的优化手段 可以通过索引加快查询的速度 避免针对表遍历 索引缺点&#xff1a; 1.占用更多空间&#xff0c;生成索引需要一系列数据结构 一系列额外数据 2.可能会降低插入修改删除的速度 ps.如果这个表本来就很大&#xff0c;创建索引容易把数据库服务…

leetcode hot100刷题日记——32.杨辉三角

class Solution { public:vector<vector<int>> generate(int numRows) {//感觉是不是就是找规律遍历啊//i层共有i1个数字//i层的0和i位置都是1//i层的其他位置j的数字i-1层j-1位置i-1层j位置//注意二维vector数组的初始化vector<vector<int>>res(numRo…

数据中台(大数据平台)之元数据管理

元数据管理是数据管理的基础&#xff0c;数据中台产品要能够提供各类元数据采集的适配器&#xff0c;自动化采集技术元数据&#xff0c;并在技术元数据的基础上补充管理属性和业务属性&#xff0c;为后续的数据资源目录、数据安全管控、报表开发提供统一的口径。并能够在数据集…

TDenigne 集群可视化管理

可视化管理工具 为方便用户更高效地使用和管理 TDengine&#xff0c;TDengine 3.0 版本推出了一个全新的可视化组件 taosExplorer。这个组件旨在帮助用户在不熟悉 SQL 的情况下&#xff0c;也能轻松管理 TDengine 集群。通过 taosExplorer&#xff0c;用户可以轻松查看 TDengi…

【Linux 学习计划】-- 进程地址空间

目录 进程地址的引入 进程地址空间基础原理 区域划分的本质 如何理解进程地址空间 越界访问的本质 进一步理解写时拷贝 重谈 fork 返回值 结语 进程地址的引入 我们先来看一段代码&#xff1a; 首先我们可以看到&#xff0c;父进程和子进程是可以同时可以看到一个变量…

foundationpose位姿检测环境搭建与数据集制作

foundationpose环境搭建数据集制作 注&#xff1a;本教程为在未知明确方法的探索步骤记录&#xff0c;由于时间原因未做整理&#xff0c;可能有不必要步骤&#xff0c;建议先看完整篇文章理清思路在动手制作 创建数据集 保存RGB和Depth图像: 使用data_collect.py脚本来保存R…

某乎x-zse-96 破解(补环境版本)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、总体概述二、请求分析分析请求流程三、逆向分析总结一、总体概述 本文主要实现某乎x-zse-96 破解(补环境版本),相关的链接: https://www.zhihu.com/search?type=content&q=%25E7%258…

智慧物流园区整体解决方案

该智慧物流园区整体解决方案借助云计算、物联网、ICT 等技术,从咨询规划阶段介入,整合供应链上下游资源,实现物流自动化、信息化与智能化。方案涵盖智慧仓储管理(如自动化立体仓储系统、温湿度监控)、智慧物流(运输管理系统 TMS、GPS 监控)、智慧车辆管理(定位、调度、…

车载诊断架构SOVD --- 车辆发现与建连

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…