
jvm-01
发布日期:2021-05-08 05:28:12
浏览次数:22
分类:精选文章
本文共 1695 字,大约阅读时间需要 5 分钟。
Java类文件与类加载机制详解
官网资源
Java类的编译与执行流程
Java程序的编译与执行遵循以下流程:
源代码编译
- 代码被词法分析器(Lexer)处理,生成字符流(tokens)。
- 语法分析器(Parser)将字符流转化为抽象语法树(AST)。
- 语义分析器(Semantic Validator)验证代码的语义,生成注解抽象语法树(AST)。
- 字节码生成器(Bytecode Generator)将AST转化为Java字节码。
类文件结构
- 类文件以魔数
0xCAFEBABE
开头,这个魔数标识文件的格式。 - 类文件主要包含以下部分:
- 常量池(Constant Pool):存储编译时期生成的字面量和符号引用。
- 字段描述(Field Descriptor):描述类的静态和非静态字段。
- 方法描述(Method Descriptor):描述类的静态和非静态方法。
- 类验证器(Class Validator):确保类文件的格式和内容的正确性。
类文件与虚拟机的交互
- 类文件被加载到Java虚拟机(JVM)中。
- JVM通过类加载机制将字节码转化为运行时数据结构。
类加载机制
类加载器(ClassLoader)
- 类加载器负责将类文件加载到JVM中。
- 类加载器的工作流程:
- 找到类文件所在位置:通过类的全限定名获取定义类的字节流。
- 验证字节流:确保字节流符合Java类文件格式。
- 转换字节流:将字节流转换为运行时数据结构。
- 创建类对象:在Java堆中生成
java.lang.Class
对象。
双亲委派机制
- 当一个类加载器需要加载一个类时,它会将请求委派给其父类加载器。
- 双亲委派的作用是确保类加载的正确性和一致性。
- JVM提供三种系统加载器:
- 启动类加载器(Bootstrap ClassLoader):负责加载
<JAVA_HOME>/lib
下的类。 - 扩展类加载器(Extension ClassLoader):负责加载
<JAVA_HOME>/lib/ext
下的类。 - 应用程序类加载器(Application ClassLoader):负责加载用户应用程序的类。
- 启动类加载器(Bootstrap ClassLoader):负责加载
破坏双亲委派
- 在某些情况下,父类加载器需要委派给子类加载器。
- 例如,
DriverManager
需要加载数据库连接器实现类,这些实现类通常由系统类加载器加载。
类文件的处理流程
验证
- 文件格式验证:确保类文件符合Java规范。
- 源数据验证:验证字节码与源代码一致。
- 字节码验证:确保字节码的语法正确。
- 符号引用验证:确保符号引用指向正确的类和方法。
准备
- 为静态变量分配内存,并初始化为默认值。
- 例如,
static int a = 10;
在准备阶段仍为0。
解释
- 将符号引用转换为直接引用。
- 例如,字符串引用
String str = "address"
会转换为直接内存地址。
初始化
- 执行静态代码块和静态变量初始化。
- 例如,
static { a = 10; }
会在初始化阶段执行。
运行时数据区(Run-Time Data Areas)
方法区(Method Area)
- 方法区是线程共享的内存区域。
- 在JDK 8中,方法区称为元空间(Metaspace),在JDK 6和7中称为永久代(Perm Space)。
- 方法区主要存储:
- 运行时常量池(Run-Time Constant Pool):存储编译时期生成的字面量和符号引用。
堆(Heap)
- 堆是Java虚拟机管理的最大内存块。
- 堆用于存储Java对象实例和数组。
虚拟机栈(Virtual Machine Stack)
- 虚拟机栈是线程私有的内存区域。
- 用于存储线程执行方法调用状态。
- 每个线程都有自己的栈,栈帧表示方法调用。
程序计数器(Program Counter)
- 每个线程有独立的程序计数器。
- 记录当前线程执行的虚拟机字节码指令地址。
本地方法栈(Native Method Stack)
- 用于存储本地方法(Native Method)的执行状态。
通过以上机制,Java类文件被成功加载到JVM中,确保程序正常运行。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年03月28日 04时06分37秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
delete对象时会自动调用类的析构函数
2019-03-06
C++ 子类对象直接赋值给父类对象可行,反过来不行
2019-03-06
linux下同一个动态库名为何辣么多的.so文件
2019-03-06
SQL联表的方式(逗号, Left Join, Right Join)
2019-03-06
牛客网输入输出举例
2019-03-06
字符串初始化时的注意点
2019-03-06
软考相关试题
2019-03-06
顺序表的操作
2019-03-06
常量表达式
2019-03-06
POD类型
2019-03-06
const与常量,傻傻分不清楚~
2019-03-06
Head First设计模式——迭代器模式
2019-03-06
MongoDB版本及存储引擎区别
2019-03-06
shell echo单行和多行文字定向写入到文件中
2019-03-06
AtCoder Beginner Contest 100 题解
2019-03-06
【数据结构】可持久化线段树初步
2019-03-06
Java高性能编程之CAS与ABA及解决方法
2019-03-06
从BIO到Netty的演变
2019-03-06
《算法导论》第二章笔记
2019-03-06
HTML节点操作
2019-03-06