一、源码架构概览
目标:OpenJDK HotSpot JVM(JDK 8u)
源码:https://github.com/openjdk/jdk8u
核心路径:hotspot/src/share/vm/
许可证:GPL v2
分析日期:2026-09-07
1.1 目录结构
hotspot/src/share/vm/ ├── oops/ # 对象模型 (Ordinary Object Pointers) ├── interpreter/ # 字节码解释器 ├── c1/ # C1 客户端编译器 ├── opto/ # C2 服务器编译器 ├── gc_implementation/ # 垃圾回收实现 ├── memory/ # 内存管理 ├── runtime/ # 运行时环境 ├── classfile/ # 类文件解析与加载 ├── prims/ # 基本操作 (JNI/Unsafe) ├── compiler/ # 编译器调度 ├── code/ # 代码缓存 ├── services/ # 诊断服务 └── utilities/ # 工具类1.2 模块依赖关系
┌─────────────────────────────────────────────────────────────┐ │ 应用层 (Java) │ └──────────────────────────┬──────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ 执行引擎层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Interpreter │ │ C1 Compiler │ │ C2 Compiler │ │ │ │ (模板解释器) │ │ (客户端JIT) │ │ (服务器JIT) │ │ │ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │ └─────────┼─────────────────┼───────────────────┼────────────┘ │ │ │ ┌─────────▼─────────────────▼───────────────────▼────────────┐ │ 运行时层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Runtime │ │ Memory │ │ Class Loading │ │ │ │ (线程/锁) │ │ (堆/GC) │ │ (类加载器) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ └────────────────────────────────────────────────────────────┘ │ ┌──────────────────────────▼──────────────────────────────────┐ │ 对象模型层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ oopDesc │ │ Klass │ │ Method │ │ │ │ (对象实例) │ │ (类元数据) │ │ (方法元数据) │ │ │ └──────────────┘ └──────────────┘ └──────────────────┘ │ └────────────────────────────────────────────────────────────┘二、对象模型逆向分析
2.1 oopDesc — 对象基类
源码:hotspot/src/share/vm/oops/oop.hpp
class oopDesc { private: volatile markOop _mark; // 对象头:锁/哈希/GC标记 union _metadata { Klass* _klass; // 类元数据指针 narrowKlass _compressed_klass; // 压缩类指针 (64位优化) } _metadata; public: // 对象头访问 markOop mark() const { return _mark; } void set_mark(volatile markOop m) { _mark = m; } // 类元数据访问 Klass* klass() const; void set_klass(Klass* k); // 对象大小计算 static int header_size() { return sizeof(oopDesc)/HeapWordSize; } // 类型判断 bool is_instance() const; bool is_array() const; bool is_objArray() const; bool is_typeArray() const; // 字段访问 (偏移量方式) oop obj_field(int offset) const; void obj_field_put(int offset, oop value); jint int_field(int offset) const; void int_field_put(int offset, jint contents); // GC 相关 bool is_gc_marked() const; bool is_forwarded() const; void forward_to(oop p); // 锁状态判断 bool is_locked() const; bool is_unlocked() const; bool has_bias_pattern() const; // 哈希码 intptr_t identity_hash(); };逆向结论:
| 字段 | 偏移量 | 大小 | 用途 |
|---|---|---|---|
_mark | 0 | 8 bytes | 锁状态、GC标记、哈希码、分代年龄 |
_metadata | 8 | 8 bytes(或4字节压缩) | 指向Klass元数据 |
对象内存布局:
┌─────────────────────────────────────────────────────────────┐ │ Java Object Layout │ ├─────────────────────────────────────────────────────────────┤ │ Offset 0: markOop _mark (8 bytes) │ │ ├── hash_code: 31 bits │ │ ├── age: 4 bits (分代年龄) │ │ ├── biased_lock: 1 bit │ │ ├── lock: 2 bits (锁状态) │ │ └── gc_mark: 1 bit │ │ │ │ Offset 8: Klass* _klass (8 bytes / 4 bytes) │ │ └── 指向类元数据 │ │ │ │ Offset 16: Instance Data (variable) │ │ ├── 父类字段 │ │ └── 子类字段 │ │ │ │ Padding: Alignment (0-7 bytes) │ │ └── 确保对象大小是8字节倍数 │ └─────────────────────────────────────────────────────────────┘2.2 markOop — 对象头结构
源码:hotspot/src/share/vm/oops/markOop.hpp
// 无锁状态 (匿名对象) // [hash_code:31 | unused:1 | age:4 | biased_lock:0 | lock:01] [64 bits] // 偏向锁状态 // [thread:54 | epoch:2 | age:4 | biased_lock:1 | lock:01] [64 bits] // 轻量级锁状态 // [ptr_to_lock_record:62 | lock:00] [64 bits] // 重量级锁状态 // [ptr_to_heavyweight_monitor:62 | lock:10] [64 bits] // GC标记状态 // [forward_ptr:62 | gc_mark:11] [64 bits] class markOopDesc { private: uintptr_t _value; public: // 锁状态判断 bool is_unlocked() const; bool is_locked() const; bool is_marked() const; // GC标记 bool has_bias_pattern() const; // 哈希码提取 intptr_t hash() const; // 年龄操作 uint age() const; markOop incr_age(); // 锁状态转换 markOop set_marked() const; markOop set_unlocked() const; };锁升级机制:
┌─────────────────────────────────────────────────────────────┐ │ Lock Escalation │ ├─────────────────────────────────────────────────────────────┤ │ 1. 无锁 (Unlocked) │ │ markOop = [hash:31 | age:4 | 0 | 01] │ │ │ │ 2. 偏向锁 (Biased) │ │ 首次同步时,将线程ID写入markOop │ │ markOop = [thread_id:54 | epoch:2 | age:4 | 1 | 01] │ │ 后续该线程进入同步块无需CAS操作 │ │ │ │ 3. 轻量级锁 (Lightweight) │ │ 偏向锁撤销后升级 │ │ markOop = [lock_record_ptr:62 | 00] │ │ lock_record指向栈上的BasicLock结构 │ │ │ │ 4. 重量级锁 (Heavyweight) │ │ 轻量级锁膨胀后升级 │ │ markOop = [monitor_ptr:62 | 10] │ │ monitor指向ObjectMonitor对象 │ └─────────────────────────────────────────────────────────────┘2.3 Klass — 类元数据
源码:hotspot/src/share/vm/oops/klass.hpp
class Klass: public Metadata { protected: // 类基本信息 juint _layout_helper; // 对象大小计算辅助值 jint _super_check_offset; // 父类检查偏移 oop _java_mirror; // 对应的java.lang.Class对象 // 类层次结构 Klass* _super; // 父类 Klass* _next_sibling; // 兄弟类 Klass* _next_link; // 链表指针 // 虚方法表 Array<Klass*>* _secondary_super_cache; Array<Klass*>* _secondary_supers; // 名称 Symbol* _name; // 类名 (符号引用) public: // 对象创建 instanceOop allocate_instance(TRAPS); // 方法查找 Method* method_with_idnum(int idnum); // 虚方法表 Method** start_of_vtable() const; int vtable_length() const; // 接口表 Array<Klass*>* local_interfaces() const; Array<Klass*>* transitive_interfaces() const; }; class InstanceKlass: public Klass { protected: // 字段信息 Array<u2>* _fields; // 字段描述符数组 int _java_fields_count; // Java声明的字段数 // 方法信息 Array<Method*>* _methods; // 方法数组 int _method_ordering; // 方法排序 // 常量池 ConstantPool* _constants; // 常量池 // 类加载器 oop _class_loader; // 类加载器对象 oop _protection_domain; // 保护域 // 初始化状态 ClassState _init_state; // 初始化状态 Thread* _init_thread; // 初始化线程 // 实例大小 jint _layout_helper; // 实例大小辅助值 int _static_field_size; // 静态字段大小 int _nonstatic_field_size; // 非静态字段大小 public: // 类初始化 void initialize(TRAPS); // 字段访问 FieldStream fields() const; int nof_fields() const; // 方法访问 Method* find_method(Symbol* name, Symbol* signature) const; // 对象分配 instanceOop allocate_instance(TRAPS); };InstanceKlass 内存布局:
┌─────────────────────────────────────────────────────────────┐ │ InstanceKlass Structure │ ├─────────────────────────────────────────────────────────────┤ │ Klass Header │ │ ├── _layout_helper │ │ ├── _super (父类指针) │ │ ├── _java_mirror (Class对象) │ │ └── _name (类名Symbol) │ │ │ │ InstanceKlass Fields │ │ ├── _constants (常量池) │ │ │ ├── cp_tags[] (常量类型数组) │ │ │ ├── cp_cache (常量池缓存) │ │ │ └── operands[] (常量值数组) │ │ │ │ │ ├── _fields (字段描述符) │ │ │ ├── access_flags (访问标志) │ │ │ ├── name_index (名称索引) │ │ │ ├── signature_index (签名索引) │ │ │ └── initval_index (初始值索引) │ │ │ │ │ ├── _methods (方法数组) │ │ │ ├── Method*[] (方法元数据指针) │ │ │ └── 每个Method包含: │ │ │ ├── ConstMethod* (字节码、行号表) │ │ │ ├── MethodData* (性能数据) │ │ │ └── ExceptionTable* (异常表) │ │ │ │ │ ├── _class_loader (类加载器) │ │ ├── _protection_domain (保护域) │ │ └── _init_state (初始化状态) │ └─────────────────────────────────────────────────────────────┘三、执行引擎逆向分析
3.1 模板解释器
源码:hotspot/src/share/vm/interpreter/templateInterpreter.hpp
class TemplateInterpreter: public AbstractInterpreter { protected: // 解释器代码表 static address _byte_code_table[Bytecodes::number_of_codes]; static address _native_entry[MethodKind::number_of_method_entries]; // 代码缓存 static InterpreterCodelet* _code; public: // 初始化 static void initialize(); // 字节码入口获取 static address entry_for_bytecode(Bytecodes::Code code) { return _byte_code_table[code]; } // 方法入口 static address entry(MethodKind kind); }; // 模板定义 class Template { private: address _entry; // 代码入口 StackDirection _stack_direction; // 栈方向 int _stack_effect; // 栈效果 public: void generate(InterpreterMacroAssembler* masm); }; // 字节码模板示例 (iadd) void Template::generate_iadd() { // 从操作数栈弹出两个int __ pop(rax); __ pop(rbx); // 相加 __ addptr(rax, rbx); // 压入结果 __ push(rax); // 返回dispatch __ dispatch_next(); }解释器执行流程:
┌─────────────────────────────────────────────────────────────┐ │ Template Interpreter Execution │ ├─────────────────────────────────────────────────────────────┤ │ 1. 方法调用入口 │ │ ├── 创建栈帧 (Stack Frame) │ │ ├── 初始化局部变量表 │ │ └── 设置操作数栈指针 │ │ │ │ 2. 字节码分发循环 │ │ main_dispatch: │ │ bytecode = *pc++ │ │ entry = _byte_code_table[bytecode] │ │ goto entry │ │ │ │ 3. 字节码执行 (以iadd为例) │ │ iadd_entry: │ │ pop rax ; 弹出第二个操作数 │ │ pop rbx ; 弹出第一个操作数 │ │ add rax, rbx ; 相加 │ │ push rax ; 压入结果 │ │ goto main_dispatch ; 继续下一条 │ │ │ │ 4. 方法返回 │ │ ├── 从操作数栈获取返回值 │ │ ├── 恢复调用者栈帧 │ │ └── 跳转到返回地址 │ └─────────────────────────────────────────────────────────────┘3.2 C1 编译器
源码:hotspot/src/share/vm/c1/c1_Compiler.hpp
class Compiler: public AbstractCompiler { public: // 编译入口 void compile_method(ciEnv* env, ciMethod* method, int entry_bci); private: // 编译流程 void build_graph(ciMethod* method); void optimize_graph(); void generate_code(); }; // 中间表示 class IR { private: Compilation* _compilation; BlockList* _hierarchy; // 基本块列表 public: // 构建HIR (High-level IR) void build_hir(); // 优化 void eliminate_null_checks(); void eliminate_sparse_conditional_branches(); void do_inlining(); void constant_propagation(); // 转换为LIR void build_lir(); }; // 低级中间表示 class LIR_List { private: GrowableArray<LIR_Op*>* _operations; public: // 指令生成 void move(LIR_Opr src, LIR_Opr dest); void leal(LIR_Address* addr, LIR_Opr dest); void call(LIR_Opr addr, LIR_OprList* args); void branch(Condition cond, BlockBegin* target); };C1 编译流程:
┌─────────────────────────────────────────────────────────────┐ │ C1 Compilation Pipeline │ ├─────────────────────────────────────────────────────────────┤ │ Stage 1: Bytecode → HIR (High-level IR) │ │ ├── GraphBuilder 遍历字节码 │ │ ├── 构建控制流图 (CFG) │ │ └── 生成 HIR 指令序列 │ │ │ │ Stage 2: HIR 优化 │ │ ├── 空检查消除 (Null Check Elimination) │ │ ├── 条件分支优化 │ │ ├── 方法内联 (Inlining) │ │ └── 常量传播 (Constant Propagation) │ │ │ │ Stage 3: HIR → LIR (Low-level IR) │ │ ├── 指令选择 (Instruction Selection) │ │ ├── 寄存器分配 (Linear Scan) │ │ └── 栈帧布局 │ │ │ │ Stage 4: 代码生成 │ │ ├── LIR → 机器码 │ │ ├── 写入代码缓存 (CodeCache) │ │ └── 安装 nmethod,回填方法入口 │ └─────────────────────────────────────────────────────────────┘3.3 C2 编译器
源码:hotspot/src/share/vm/opto/compile.hpp
class Compile : public Phase { private: // 编译上下文 ciEnv* _env; // 编译环境 ciMethod* _method; // 被编译方法 // 图结构 PhaseGVN* _gvn; // 全局值编号 Node* _root; // 图根节点 Unique_Node_List _worklist; // 工作列表 // 优化阶段 void inline_calls(); // 方法内联 void optimize_virtual_calls(); // 虚调用优化 void do_escape_analysis(); // 逃逸分析 void do_loop_optimizations(); // 循环优化 public: // 编译入口 void Optimize(); void Code_Gen(); // 图构建 Node* build_start(); // 构建起始节点 void build_graph(); // 构建理想图 }; // 理想图节点 class Node { public: virtual Node* Ideal(PhaseGVN* gvn, bool can_reshape); virtual uint hash() const; virtual bool eq(Node* other) const; };C2 编译流程:
┌─────────────────────────────────────────────────────────────┐ │ C2 Compilation Pipeline │ ├─────────────────────────────────────────────────────────────┤ │ Phase 1: 解析与图构建 │ │ ├── Parse 字节码,构建 Sea-of-Nodes 理想图 │ │ ├── 内联热点方法 (Inlining) │ │ └── 构建控制流与数据流 │ │ │ │ Phase 2: 理想化与优化 │ │ ├── GVN (Global Value Numbering) 全局值编号 │ │ ├── IGVN 迭代优化 │ │ ├── 逃逸分析 (Escape Analysis) │ │ │ ├── 标量替换 (Scalar Replacement) │ │ │ └── 锁消除 (Lock Elision) │ │ ├── 循环优化 (Loop Unrolling / Peeling) │ │ └── 死代码消除 (Dead Code Elimination) │ │ │ │ Phase 3: 指令选择与调度 │ │ ├── 匹配机器指令 (Matcher) │ │ ├── 指令调度 (Scheduling) │ │ └── 寄存器分配 (Graph Coloring) │ │ │ │ Phase 4: 代码生成 │ │ ├── 生成机器码 │ │ ├── 写入 CodeCache │ │ └── 安装 nmethod │ └─────────────────────────────────────────────────────────────┘3.4 分层编译
源码:hotspot/src/share/vm/compiler/compileBroker.hpp
class CompileBroker : AllStatic { private: static CompilerThread* _compiler_threads[]; static int _compiler_thread_count; public: // 编译请求 static void compile_method(ciEnv* env, ciMethod* target, int hot_count, CompileTask::CompileReason reason, TRAPS); // 编译队列 static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count); static void compiler_thread_loop(); }; // 编译级别 enum CompLevel { CompLevel_none = 0, // 解释执行 CompLevel_simple = 1, // C1 无 profiling CompLevel_limited_profile = 2,// C1 有限 profiling CompLevel_full_profile = 3, // C1 完整 profiling CompLevel_full_optimization = 4 // C2 深度优化 };分层编译级别流转:
┌─────────────────────────────────────────────────────────────┐ │ Tiered Compilation Levels │ ├─────────────────────────────────────────────────────────────┤ │ Level 0: 解释器执行 │ │ └── 收集方法调用次数、循环回边次数 │ │ │ │ Level 1: C1 编译 (无 profiling) │ │ └── 方法简单、无需 C2 优化时直接使用 │ │ │ │ Level 2: C1 编译 (有限 profiling) │ │ └── 收集少量类型信息,为 C2 做准备 │ │ │ │ Level 3: C1 编译 (完整 profiling) │ │ └── 收集完整类型信息、分支概率 │ │ │ │ Level 4: C2 编译 (深度优化) │ │ └── 基于 profiling 数据做激进优化 │ │ │ │ 降级: Level 4 → Level 0 │ │ └── 激进优化假设失效时 (uncommon trap) 退回解释执行 │ └─────────────────────────────────────────────────────────────┘四、垃圾回收逆向分析
4.1 堆内存结构
源码:hotspot/src/share/vm/memory/collectedHeap.hpp
class CollectedHeap : public CHeapObj<mtInternal> { protected: // 堆内存范围 MemRegion _reserved; // 保留内存区域 // 屏障集 BarrierSet* _barrier_set; // GC 状态 bool _is_gc_active; public: // 内存分配 HeapWord* obj_allocate(KlassHandle klass, int size, TRAPS); HeapWord* array_allocate(KlassHandle klass, int size, int length, TRAPS); // GC 接口 virtual void collect(GCCause::Cause cause) = 0; virtual bool is_in_reserved(const void* p) const; // 容量信息 virtual size_t capacity() const = 0; virtual size_t used() const = 0; }; // 分代堆 class GenCollectedHeap : public CollectedHeap { private: Generation* _young_gen; // 新生代 Generation* _old_gen; // 老年代 public: void collect(GCCause::Cause cause); void do_collection(bool full, bool clear_all_soft_refs, size_t size, bool is_tlab); };4.2 分代模型
┌─────────────────────────────────────────────────────────────┐ │ Generational Heap Layout │ ├─────────────────────────────────────────────────────────────┤ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Young Generation (新生代) │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ Eden │ │ Survivor │ │ Survivor │ │ │ │ │ │ │ │ S0 │ │ S1 │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ 新对象分配 → Eden,Minor GC 后存活对象在 S0/S1 间复制 │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ 晋升 (Promotion) │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Old Generation (老年代) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ 长期存活对象 / 大对象直接分配 │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Permanent / Metaspace (JDK8 起为 Metaspace) │ │ │ │ └── 类元数据、方法元数据、常量池 │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘4.3 常见 GC 算法
| 收集器 | 作用范围 | 算法 | 特点 |
|---|---|---|---|
| Serial | 新生代 / 老年代 | 复制 / 标记-整理 | 单线程,STW 时间长,适合小堆 |
| ParNew | 新生代 | 复制 | Serial 的多线程版本 |
| Parallel Scavenge | 新生代 | 复制 | 关注吞吐量,自适应调节 |
| Parallel Old | 老年代 | 标记-整理 | 与 Parallel Scavenge 配合 |
| CMS | 老年代 | 标记-清除 | 并发收集,低停顿,有碎片 |
| G1 | 整堆 | Region + 复制 | 可预测停顿,分 Region 管理 |
4.4 G1 收集器
源码:hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
class G1CollectedHeap : public SharedHeap { private: // Region 管理 G1RegionMappingChangedListener _listener; HeapRegion* _hrs; // Region 数组 uint _n_regions; // Region 数量 // 记忆集 G1RemSet* _g1_rem_set; // RSet (Remembered Set) // 收集集合 CollectionSetChooser* _cset_chooser; public: // 分配 HeapWord* allocate_new_tlab(size_t word_size); // 收集 bool do_collection_pause_at_safepoint(double target_pause_time_ms); // Region 操作 HeapRegion* region_at(uint index) const; uint num_regions() const; };G1 回收流程:
┌─────────────────────────────────────────────────────────────┐ │ G1 Collection Cycle │ ├─────────────────────────────────────────────────────────────┤ │ Phase 1: Initial Mark (STW) │ │ ├── 标记 GC Roots 直接可达对象 │ │ └── 通常伴随一次 Young GC │ │ │ │ Phase 2: Concurrent Mark │ │ ├── 遍历对象图,标记存活对象 │ │ ├── SATB (Snapshot-At-The-Beginning) 算法 │ │ └── 应用线程并发执行 │ │ │ │ Phase 3: Final Mark (STW) │ │ ├── 处理 SATB 队列中的剩余引用 │ │ └── 计算每个 Region 的存活对象比例 │ │ │ │ Phase 4: Cleanup (STW) │ │ ├── 计算 Region 的回收价值 │ │ ├── 选择回收价值最高的 Region 加入 CSet │ │ └── 重置 RSet │ │ │ │ Phase 5: Evacuation (STW) │ │ ├── 复制 CSet 中的存活对象到空闲 Region │ │ ├── 更新所有引用 │ │ └── 释放原 Region │ └─────────────────────────────────────────────────────────────┘五、运行时环境逆向分析
5.1 线程模型
源码:hotspot/src/share/vm/runtime/thread.hpp
class JavaThread: public Thread { private: // 栈信息 address _stack_base; // 栈底 size_t _stack_size; // 栈大小 // 线程状态 JavaThreadState _thread_state; // 线程状态 // Java帧锚点 JavaFrameAnchor _anchor; // 本地变量 ThreadLocalStorage _tls; public: // 线程入口 static void thread_main(JavaThread* thread); // 方法调用 void invoke_method(methodHandle method, ...); // 安全点检查 bool at_safepoint() const; void safepoint_check(); // 栈帧遍历 JavaFrameAnchor* frame_anchor(); frame last_frame(); }; // 线程状态枚举 enum JavaThreadState { _thread_uninitialized = 0, // 未初始化 _thread_new = 1, // 新建 _thread_in_native = 2, // 执行本地代码 _thread_in_vm = 3, // 执行VM代码 _thread_in_Java = 4, // 执行Java代码 _thread_blocked = 5, // 阻塞 _thread_trans_in_Java = 6, // Java状态转换中 _thread_trans_native = 7, // 本地状态转换中 _thread_trans_vm = 8 // VM状态转换中 };Java 栈帧结构:
┌─────────────────────────────────────────────────────────────┐ │ Java Stack Frame │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Local Variables │ │ │ │ ├── 参数 (args[0], args[1], ...) │ │ │ │ └── 局部变量 (var1, var2, ...) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Operand Stack │ │ │ │ ├── 操作数 (op1, op2, ...) │ │ │ │ └── 中间计算结果 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Frame Data │ │ │ │ ├── 指向运行时常量池的引用 │ │ │ │ ├── 方法返回地址 │ │ │ │ └── 调用者栈帧指针 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ High Address ← SP (Stack Pointer) │ │ ↑ │ │ │ Stack grows downward │ │ ↓ │ │ Low Address │ └─────────────────────────────────────────────────────────────┘5.2 锁实现
源码:hotspot/src/share/vm/runtime/synchronizer.hpp
class ObjectSynchronizer { public: // 进入监视器 (加锁) static void enter(Handle obj, BasicLock* lock, TRAPS); // 退出监视器 (解锁) static void exit(Handle obj, BasicLock* lock, TRAPS); // 等待 static void wait(Handle obj, jlong millis, TRAPS); // 通知 static void notify(Handle obj, TRAPS); static void notifyAll(Handle obj, TRAPS); }; // 对象监视器 class ObjectMonitor { private: // 基本信息 volatile markOop _header; // 对象头 volatile jint _count; // 重入次数 // 等待队列 ObjectWaiter* _WaitSet; // wait()队列 volatile jint _WaitSetLock; // wait队列锁 // 竞争队列 ObjectWaiter* volatile _EntryList; // 竞争锁的线程队列 // 所有者线程 Thread* _owner; // 当前持有锁的线程 // 自旋统计 volatile jint _SpinFreq; // 自旋频率 volatile jint _SpinClock; // 自旋时钟 public: void enter(TRAPS); void exit(bool has_exception, TRAPS); void wait(jlong millis, TRAPS); void notify(TRAPS); void notifyAll(TRAPS); }; // 等待者节点 class ObjectWaiter: public CHeapObj<mtSynchronizer> { public: ObjectWaiter* _next; // 下一个 ObjectWaiter* _prev; // 上一个 Thread* _TThread; // 线程 ParkEvent* _event; // 事件 volatile int _notified; // 是否已通知 };锁升级详细流程:
┌─────────────────────────────────────────────────────────────┐ │ Lock Escalation Details │ ├─────────────────────────────────────────────────────────────┤ │ 1. 无锁 → 偏向锁 │ │ 条件: 首次调用 synchronized │ │ 操作: │ │ ├── CAS 将线程ID写入 markOop │ │ ├── 设置 biased_lock 标志位 │ │ └── 后续该线程进入同步块直接通过 │ │ │ │ 2. 偏向锁 → 轻量级锁 │ │ 条件: 另一个线程尝试获取锁 │ │ 操作: │ │ ├── 检查 markOop 中的线程ID │ │ ├── 如果不是当前线程,撤销偏向锁 │ │ ├── 在栈帧中创建 BasicLock 结构 │ │ └── CAS 将 markOop 替换为 BasicLock 指针 │ │ │ │ 3. 轻量级锁 → 重量级锁 │ │ 条件: CAS 自旋失败 (竞争激烈) │ │ 操作: │ │ ├── 创建 ObjectMonitor 对象 │ │ ├── 将 ObjectMonitor 指针写入 markOop │ │ ├── 将当前线程加入 EntryList │ │ └── 阻塞当前线程 (park) │ │ │ │ 4. 锁释放 │ │ ├── 如果是偏向锁,不做任何操作 │ │ ├── 如果是轻量级锁,CAS 恢复 markOop │ │ └── 如果是重量级锁,从 ObjectMonitor 释放 │ └─────────────────────────────────────────────────────────────┘六、类加载逆向分析
6.1 类文件解析
源码:hotspot/src/share/vm/classfile/classFileParser.hpp
class ClassFileParser { private: ClassFileStream* _stream; // 类文件流 constantPoolHandle _cp; // 常量池 // 解析结果 instanceKlassHandle _klass; // 解析方法 void parseClassFile(ClassFileStream* stream, ...); // 各部分解析 void parse_constant_pool(TRAPS); void parse_interfaces(TRAPS); void parse_fields(TRAPS); void parse_methods(TRAPS); void parse_attributes(TRAPS); public: instanceKlassHandle create_instance_klass(bool changed_by_loadhook, TRAPS); }; // 常量池解析 void ClassFileParser::parse_constant_pool(TRAPS) { int length = _stream->get_u2(); _cp = ConstantPool::allocate(_loader_data, length, CHECK_NULL); for (int index = 1; index < length; index++) { jbyte tag = _stream->get_u1(); switch (tag) { case JVM_CONSTANT_Utf8: parse_utf8_entry(index); break; case JVM_CONSTANT_Integer: parse_integer_entry(index); break; case JVM_CONSTANT_Class: parse_class_entry(index); break; // ... 其他常量类型 } } }6.2 类加载流程
源码:hotspot/src/share/vm/classfile/systemDictionary.hpp
class SystemDictionary: public AllStatic { private: // 系统类加载器 static oop _java_system_loader; // 核心类缓存 static Klass* _well_known_klasses[]; public: // 加载类 static instanceKlassHandle resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS); // 查找已加载的类 static Klass* find(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); }; // 类加载器 class ClassLoader: public AllStatic { public: // 加载类文件 static instanceKlassHandle load_classfile(Symbol* h_name, TRAPS); // 搜索路径 static const char* classpath_entry(int n); static int num_classpath_entries(); };类加载完整流程:
┌─────────────────────────────────────────────────────────────┐ │ Class Loading Process │ ├─────────────────────────────────────────────────────────────┤ │ Step 1: Loading │ │ ├── 通过类名获取二进制流 │ │ ├── 读取 .class 文件字节 │ │ └── 创建 Class 对象 (存储在方法区) │ │ │ │ Step 2: Linking │ │ ├── Verification (验证) │ │ │ ├── 字节码格式验证 │ │ │ ├── 语义验证 │ │ │ └── 字节码验证 (数据流分析) │ │ │ │ │ ├── Preparation (准备) │ │ │ ├── 为类变量分配内存 │ │ │ └── 设置零值 (0, null, false) │ │ │ │ │ └── Resolution (解析) │ │ ├── 符号引用 → 直接引用 │ │ ├── 常量池解析 │ │ └── 类/接口解析 │ │ │ │ Step 3: Initialization (初始化) │ │ ├── 执行 <clinit>() 方法 │ │ ├── 静态变量赋初值 │ │ └── 执行静态代码块 │ └─────────────────────────────────────────────────────────────┘七、关键数据结构总结
7.1 核心结构对照表
| Java 概念 | HotSpot 实现 | 源码位置 |
|---|---|---|
| Java 对象 | oopDesc | oops/oop.hpp |
| 对象头 | markOop | oops/markOop.hpp |
| 类元数据 | InstanceKlass | oops/instanceKlass.hpp |
| 方法元数据 | Method | oops/method.hpp |
| 常量池 | ConstantPool | oops/constantPool.hpp |
| Java 线程 | JavaThread | runtime/thread.hpp |
| 监视器锁 | ObjectMonitor | runtime/synchronizer.hpp |
| 堆内存 | CollectedHeap | memory/heap.hpp |
| 栈帧 | frame | runtime/frame.hpp |
7.2 关键指针关系
┌─────────────────────────────────────────────────────────────┐ │ Pointer Relationships │ ├─────────────────────────────────────────────────────────────┤ │ Java Object (oopDesc) │ │ ├── _mark → markOop (锁/哈希/GC标记) │ │ └── _klass → InstanceKlass (类元数据) │ │ ├── _constants → ConstantPool (常量池) │ │ ├── _methods → Method[] (方法数组) │ │ │ └── Method → ConstMethod (字节码) │ │ ├── _fields → Field[] (字段数组) │ │ ├── _super → Klass (父类) │ │ └── _java_mirror → Class 对象 │ │ │ │ JavaThread │ │ ├── _stack_base → 栈底地址 │ │ ├── _anchor → JavaFrameAnchor (帧锚点) │ │ │ └── _last_Java_sp → 最后 Java 栈帧指针 │ │ └── _thread_state → 线程状态 │ │ │ │ CollectedHeap │ │ ├── _reserved → 堆内存范围 │ │ ├── _barrier_set → 写屏障 │ │ └── (子类) GenCollectedHeap │ │ ├── _young_gen → 新生代 │ │ └── _old_gen → 老年代 │ └─────────────────────────────────────────────────────────────┘八、逆向分析工具与方法
8.1 源码分析工具
# 代码浏览 # 使用 IDE (CLion/VSCode) 打开 hotspot/src/share/vm/ 符号搜索 grep -r "class oopDesc" hotspot/src/share/vm/ 调用关系 grep -r "allocate_instance" hotspot/src/share/vm/ 宏定义追踪 grep -r "define.*oop" hotspot/src/share/vm/8.2 运行时调试
# 使用 GDB 调试 JVM gdb --args java -XX:+PrintCompilation Test 常用断点 (gdb) break oopDesc::mark (gdb) break InstanceKlass::initialize (gdb) break SafepointSynchronize::begin 打印对象 (gdb) call ((oop)0x12345678)->print() 查看堆信息 (gdb) call Universe::heap()->print_on(tty)8.3 JVM 参数调试
# 打印类加载 java -verbose:class Test 打印 GC java -verbose:gc -XX:+PrintGCDetails Test 打印 JIT 编译 java -XX:+PrintCompilation Test 打印对象布局 java -XX:+PrintFieldLayout Test 打印汇编代码 java -XX:+PrintAssembly Test 打印锁信息 java -XX:+PrintSafepointStatistics Test 打印内存分配 java -XX:+PrintTLAB Test九、逆向分析结论
9.1 HotSpot 架构特点
| 特性 | 实现方式 |
|---|---|
| 对象模型 | oopDesc + Klass 分离,对象头存储锁/哈希信息 |
| 执行引擎 | 模板解释器 + C1/C2 双编译器 |
| 内存管理 | 分代堆 + 多种 GC 算法 |
| 锁机制 | 偏向锁 → 轻量级锁 → 重量级锁升级 |
| 类加载 | 双亲委派 + 懒加载 |
9.2 关键优化技术
| 优化 | 实现位置 | 效果 |
|---|---|---|
| 压缩指针 | -XX:+UseCompressedOops | 64 位系统节省 40% 堆内存 |
| TLAB | 线程本地分配缓冲区 | 减少分配锁竞争 |
| 内联缓存 | 多态内联缓存 | 加速虚方法调用 |
| 逃逸分析 | C2 编译器 | 标量替换、锁消除 |
| 分层编译 | C1 + C2 协作 | 快速启动 + 深度优化 |
9.3 安全机制
| 机制 | 实现 |
|---|---|
| 字节码验证 | ClassFileParser 中的验证阶段 |
| 栈溢出检查 | 每个方法入口检查栈空间 |
| 空指针检查 | 解释器/JIT 插入空检查 |
| 数组边界检查 | 每次数组访问检查边界 |
| 安全点 | GC 时所有线程到达安全点 |
报告完成