尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
JVM规范学习总结解释器与JIT编译器如何处理JVM字节码前言解释器与 JIT 编译器如何处理 JVM 字节码一、学习目标理解字节码如何转化为 CPU 执行的指令二、先建立完整的执行路径三、JVMS 如何定义字节码的执行1. 字节码不是直接对应 CPU 指令2. 使用一个示例理解字节码四、解释器如何处理 JVM 字节码1. 解释器的核心工作流程2. HotSpot 的模板解释器3. 解释器为什么通常效率较低五、JIT 编译器如何处理字节码1. JIT 的目标从字节码生成优化机器码2. HotSpot 的 C1 与 C23. JIT 如何判断一个方法是热点4. JIT 如何将字节码转化为中间表示六、JIT 的关键优化机制1. 方法内联Inlining2. 基于类型剖析的优化3. 其他常见优化七、JIT 优化后JVM 如何保证程序语义正确1. 去优化Deoptimization2. 栈上替换OSR八、从系统工程师角度验证上述结论1. 查看字节码2. 观察编译事件3. 比较解释执行与编译执行九、最终学习总结十、解释器与 JIT 编译器的源码对照总结1. 规范层与实现层的区别2. 推荐的源码阅读顺序3. 最小实验验证字节码与编译行为十一、最终结论前言本文旨在记录近期研读Java源码的学习心得与疑难问题。由于个人理解水平有限文中内容难免存在疏漏恳请读者不吝指正。解释器与 JIT 编译器如何处理 JVM 字节码一、学习目标理解字节码如何转化为 CPU 执行的指令从系统工程师的角度研究 JVM不能只停留在“Java 代码经过编译后生成字节码最后由 JVM 执行”这一层面还需要进一步回答以下问题JVM 解释器读取字节码后如何完成取指、解码、操作数处理和控制流跳转为什么解释器执行相同的字节码时通常会比经过 JIT 优化的机器码更慢JVM 如何判断一个方法或循环值得编译C1 和 C2 编译器分别负责什么JIT 编译器进行了方法内联、常量传播等优化之后如何保证程序仍满足 JVM 规范当 JIT 编译时采用的假设失效JVM 如何从机器码执行状态回到解释器本次学习以 Java SE 26 的 《Java 虚拟机规范》JVMS 为规范依据并结合 OpenJDK HotSpot 源码分析具体实现。需要先明确JVMS 规定字节码的语义和 JVM 必须满足的行为但不强制规定 JVM 必须使用某一种解释器、JIT 编译器或优化算法。 字节码翻译成宿主 CPU 的机器码是规范允许的实现方式之一。二、先建立完整的执行路径需要注意这张图表示的是典型的 HotSpot 执行路径而不是说每个方法都必定经历完整的解释器、C1、C2 流程。不同方法可能始终由解释器执行也可能只经过部分编译层级具体行为取决于 JVM 配置、编译策略、方法特征及运行时反馈。三、JVMS 如何定义字节码的执行1. 字节码不是直接对应 CPU 指令Java 编译器javac生成的是 JVM 指令例如iload_0 bipush imul iadd istore_2 if_icmple ireturn这些是 JVM 指令不是 x86-64 的IMUL、ADD或 AArch64 的MUL、ADD等宿主 CPU 指令。JVMS 第 2 章说明了 JVM 的抽象机器、运行时数据区、栈帧和指令集第 6 章定义各条指令的具体语义。JVM 实现可以采用不同的内部方式执行它们但必须满足相应的规范要求。参见 JVMS 第 2 章 与 JVMS 第 6 章。2. 使用一个示例理解字节码下面以一个简单方法作为分析对象publicfinalclassBytecodeDemo{// x、y 是参数product、result 是局部变量。staticintcalc(intx,inty){intproductx*31;intresultproducty;if(result100){returnresult;}returnresult1;}}可以使用以下命令查看编译结果javac BytecodeDemo.java javap-c-vBytecodeDemo在典型的javac输出中calc方法的字节码大致如下具体偏移和指令排列应以实际 JDK 版本的javap输出为准。iload_0 // 读取局部变量 x将值压入操作数栈 bipush 31 // 将常量 31 压入操作数栈 imul // 弹出两个 int计算乘积再将结果压栈 iload_1 // 读取局部变量 y iadd // 弹出两个 int相加并将结果压栈 istore_2 // 将计算结果保存到局部变量 product/result 对应槽位 iload_2 // 加载待判断的整数 bipush 100 // 压入比较常量 if_icmple // 比较两个整数满足条件则跳转 iload_2 // 重新加载返回值 ireturn // 返回 int 结果 // 条件跳转的另一条执行路径 iload_2 // 加载原结果 iconst_1 // 压入整数 1 iadd // 计算 result 1 ireturn // 返回 int 结果以上注释展示的是指令的职责不代表 JVM 一定将每条指令逐条转换成一条 CPU 机器指令。学习时需要特别注意局部变量表保存方法参数及部分局部变量。操作数栈字节码运算通常从栈中取出操作数再将结果压回栈中。程序计数器及当前执行位置用于确定下一条需要执行的指令具体实现不必采用规范所描述概念的字面内存布局。控制流条件分支、方法调用、返回、异常处理都可能改变执行路径。这些是 JVMS 规定的抽象执行模型。解释器可以按这个模型执行JIT 也可以把相同逻辑转换为寄存器运算、条件跳转和其他机器指令不需要继续保留原始的操作数栈形式。四、解释器如何处理 JVM 字节码1. 解释器的核心工作流程JVM 规范第 2.11 节给出了一个简化的解释器执行模型获取当前指令及其操作数执行指令定义的操作然后继续执行后续指令直到方法完成或控制流发生改变。参见 JVMS §2.11。从系统工程师的角度可以把解释器的工作划分为四个步骤。第一步读取指令根据当前执行位置读取字节码 opcode并解析必要的操作数。例如bipush 31不只包含操作码还包含整数常量31。第二步分派指令处理逻辑根据 opcode 找到对应的指令处理入口。例如iadd进入整数加法处理逻辑if_icmple进入条件比较与跳转逻辑。第三步执行指令语义读取或修改局部变量、操作数栈和对象状态执行算术运算、方法调用、异常检查等操作。第四步更新执行状态更新当前指令位置继续解释下一条指令遇到方法返回、异常或控制流跳转时则进入相应执行路径。2. HotSpot 的模板解释器在 OpenJDK HotSpot 中一个关键实现是 Template Interpreter模板解释器。它不是简单地让一个通用的 C 循环不断执行switch(opcode)。HotSpot 会针对 JVM 字节码准备相应的处理模板并由与 CPU 架构有关的代码生成逻辑创建解释器执行代码。重点源码如下源码文件研究重点templateTable.cpp定义字节码处理模板及相关指令分派信息templateInterpreterGenerator.cpp解释器代码的生成与入口组织templateTable_x86.cppx86 平台上的具体字节码处理实现interpreterRuntime.cpp解释器执行过程中需要的运行时辅助操作这些链接指向 OpenJDK 主线源码。阅读时应结合具体 JDK 版本以及实际使用的 CPU 架构不能把某一平台的实现直接等同于所有 JVM 的实现。模板解释器的概念可以表示为下面的示意代码。这是为了便于理解而编写的伪代码不是 OpenJDK 的原样源码。// 示意模板解释器的基本工作方式。// 实际 HotSpot 会使用生成的解释器代码及相应的指令分派机制。while(method_has_more_bytecodes){// 1. 读取当前 JVM 字节码。opcoderead_opcode(current_bytecode_position);// 2. 找到与该字节码关联的处理代码。handlerdispatch_table[opcode];// 3. 执行指令语义。// 例如 iadd 执行整数加法if_icmple 执行条件分支。handler.execute();// 4. 继续执行分支、返回及异常可能改变控制流。}这个模型对应的关键结论是解释器分派的是 JVM 指令而具体执行这些指令的解释器代码本身也是由宿主 CPU 的机器指令构成的。因此“解释执行”不代表 CPU 不执行机器码。它代表 JVM 还在运行时处理 JVM 指令及其对应的解释器逻辑而不是直接进入该 Java 方法经过 JIT 编译后得到的优化机器码。3. 解释器为什么通常效率较低以result product y为例执行iadd时解释器需要处理字节码对应的执行状态、操作数和指令分派。如果方法非常简单这些解释器开销相对于整数加法本身可能很显著。解释器常见的性能开销包括指令分派开销需要选择并进入当前字节码的处理逻辑。运行时状态维护需要维护与 JVM 抽象执行模型相对应的状态包括局部变量、操作数栈和异常等信息。难以充分跨指令优化单条指令的处理模式通常不具备优化编译器针对整个方法所掌握的完整优化机会。动态链接与运行时辅助调用首次解析部分符号引用或进行某些对象操作、同步和异常处理时可能需要进入运行时辅助逻辑。需要注意现代 HotSpot 解释器也有优化机制例如操作数栈顶缓存、常量池缓存以及快速字节码等。因此不能简单地认为每一条字节码都会执行一次完整的 C 函数调用或每次都访问内存中的操作数栈。从系统工程角度来看解释器的重要价值在于启动成本低、通用性强并能够在运行过程中收集热点信息。它是运行时优化的重要基础而不只是一个低性能的执行后备方案。五、JIT 编译器如何处理字节码1. JIT 的目标从字节码生成优化机器码JIT 是 Just-In-Time Compiler即即时编译器。解释器主要根据当前字节码执行相应的操作JIT 则能够分析一个方法中的多个基本块、控制流和数据依赖把字节码转化成中间表示再进行优化最终生成宿主 CPU 可以直接执行的机器码。典型流程如下字节码解析读取方法的字节码、常量池引用和控制流信息。构建中间表示建立基本块、控制流与数据依赖关系。执行编译优化根据静态信息和运行时剖析信息进行内联、常量传播等优化。生成机器码进行指令选择、寄存器分配及相关代码生成。安装编译结果将生成的代码安装到 JVM 管理的代码缓存中并使其可以被执行。HotSpot 的编译器并不是必须把每一个 JVM opcode 映射成一条独立的 CPU 指令。编译器可以重排、合并或消除操作只要保持 Java 程序要求的可观察行为和 JVM 规范约束。2. HotSpot 的 C1 与 C2在常见的 HotSpot 分层编译模式下JVM 不一定在程序启动时就把所有 Java 方法编译成高优化级别的机器码而是根据运行时信息逐渐提升热点方法的执行级别。编译级别典型执行方式主要目标Level 0解释器快速开始执行并可收集运行信息Level 1C1较少剖析快速编译减少解释执行开销Level 2C1有限剖析平衡执行速度与信息收集Level 3C1完整剖析获取更丰富的运行时信息Level 4C2优化编译对热点代码进行更深入的优化以上是常见分层编译模式的概念划分实际编译级别会受构建方式、JVM 参数和编译策略影响。并非每个方法都严格按 Level 0 → 1 → 2 → 3 → 4 的顺序经历全部级别。OpenJDK 的compilationPolicy.hpp对执行级别转换、调用计数、循环回边计数、编译队列及反馈调节机制有具体说明。其设计表明编译策略不仅考虑方法调用次数也会考虑循环执行次数以及编译器队列负载。从职责上看C1 更强调较低的编译开销和较快的代码生成速度也可以收集运行时剖析信息。C2 面向更深入的优化能够更充分地利用控制流和运行时类型等信息优化经过反复执行的热点代码。这是一种性能目标上的区分不意味着 C1 完全不做优化也不意味着 C2 对所有方法都一定更快。3. JIT 如何判断一个方法是热点JVM 的编译策略需要解决一个成本收益问题如果一个方法只执行一次将其编译成高度优化的机器码可能得不偿失。如果一个方法在高频循环中反复执行那么编译一次并重复使用生成的机器码通常更有价值。因此HotSpot 会收集并利用运行时信息例如方法调用计数、循环回边计数以及类型和分支剖析信息。**循环回边backedge**是控制流回到循环中较早位置的边。在典型的热点循环中即使方法只调用一次循环体也可能被执行数百万次所以仅统计方法调用次数并不足以判断其真实执行热度。OpenJDK 编译策略相关源码compilationPolicy.hpp。其基本逻辑可以概括为以下带注释的伪代码// 示意代码HotSpot 热点检测的概念模型。// 不是 OpenJDK 源码也不是实际 JVM 固定采用的阈值。if(methodInvocationCountExceeded()||loopBackedgeCountExceeded()){// 提交编译请求而不是在这里直接完成机器码生成。requestJitCompilation(method);}// 编译线程根据队列、当前编译级别和编译策略// 决定具体何时编译以及使用哪个编译级别。在 HotSpot 中编译请求的协调和相关任务管理可以从compileBroker.cpp继续追踪。要点是达到热点条件不等于机器码已经生成也不等于当前线程必然立即切换到新生成的机器码。 编译任务还可能需要排队、执行以及安装编译结果。4. JIT 如何将字节码转化为中间表示以 C2 为例研究入口之一是src/hotspot/share/opto/parse1.cpp这个文件中的解析逻辑负责处理方法入口、基本块和控制流等信息并将字节码解析为编译器能够进一步处理的图结构。考虑示例方法staticintcalc(intx,inty){intproductx*31;intresultproducty;if(result100){returnresult;}returnresult1;}从源代码到执行的过程中可以把数据流理解为Java 源码 | v JVM 字节码 | v C2 解析字节码建立控制流和数据依赖 | v 中间表示IR | -- 常量传播 -- 代数化简 -- 控制流优化 -- 其他适用的优化 | v 机器码生成这里的 IR 是编译器的中间表示。它使编译器不必始终拘泥于字节码原先的栈式表达而可以围绕数值、数据依赖和控制流进行优化。例如若编译器能够证明某个值恒定便可能进行常量传播如果可以证明某个检查没有必要则有机会消除对应检查。至于某次具体编译是否实施优化需要结合生成的编译日志、机器码及当时的运行时信息判断。六、JIT 的关键优化机制1. 方法内联Inlining假设存在两个方法staticintadd(inta,intb){returnab;}staticintcalculate(intx){// 如果 JIT 决定将 add 内联// 就可能把 add 的计算直接纳入调用者的优化过程。returnadd(x,1);}解释器执行普通方法调用时需要完成方法调用所需的运行时处理。如果 JIT 将add内联到calculate中编译器就可以在调用者上下文中分析x 1并有机会继续优化后续计算。内联并不只是消除一次调用开销。它的更大价值是扩大优化器能够整体分析的代码范围为常量传播、死代码消除及其他跨调用优化创造条件。不过内联受到方法大小、调用频率、调用目标是否明确及编译预算等因素的影响并非所有方法调用都会被内联。2. 基于类型剖析的优化下面的代码通过接口调用方法interfaceCalculator{intcalculate(intx);}staticintrun(Calculatorcalculator,intvalue){returncalculator.calculate(value);}若运行时剖析表明某个调用位置长期只观察到一个实现类型JIT 可能据此进行推测性优化例如将调用去虚拟化使进一步内联成为可能。但这种优化依赖运行时假设。未来如果出现此前没有观察到的实现类型原有优化可能不再适用JVM 必须通过保护性检查、去优化或重新编译等机制保证正确性。因此运行时剖析不是对程序未来行为的绝对保证而是编译器优化决策的重要依据。3. 其他常见优化优化技术系统工程师需要理解的作用常量传播利用已知常量简化表达式和分支死代码消除删除不会影响可观察结果的计算范围检查消除在条件成立时省去不必要的数组边界检查循环优化改善循环中的指令组织或减少重复计算逃逸分析分析对象是否可能被当前线程或作用域之外访问标量替换在符合条件时将对象字段拆解为独立值减少实际对象分配锁消除在能够证明同步操作不需要时消除相关锁开销以上优化并非必然发生。是否应用取决于代码形态、类型信息、编译级别、运行时状态和具体优化器能力。七、JIT 优化后JVM 如何保证程序语义正确这是理解 JVMS 与 JIT 关系时最重要的部分。JVMS 定义行为约束JIT 优化的是实现方式而不是改变程序必须遵守的语义。在编译过程中优化器需要考虑整数运算的语言语义、条件分支、方法返回、异常行为以及多线程程序的同步和内存模型约束。不能因为某种优化在单线程测试中看起来有效就认为它必然合法。例如编译器可以把多条字节码合并为更少的机器指令也可以使用寄存器保存中间结果而不必按照原有栈操作逐条执行。但如果相关操作涉及volatile、监视器或其他同步语义编译器仍然必须保持规范要求的可观察行为。从系统工程角度理解优化是否正确关键是研究哪些行为可观察、哪些变换满足语义约束、哪些推测需要运行时保护而不是简单比较字节码数量与机器指令数量。1. 去优化Deoptimization假设 JIT 根据运行时剖析推测一个调用点只会接收到某一种对象类型并在此基础上进行了内联。随后运行时条件发生变化原先的假设不再成立。JVM 不能继续无条件执行建立在失效假设上的优化代码。HotSpot 可以通过保护性检查和去优化机制退出不再适用的编译代码恢复出能够继续执行的 Java 执行状态再使用解释器或其他适用的编译代码继续执行。源码入口src/hotspot/share/runtime/deoptimization.cpp这个过程不是普通意义上的“撤销所有已经执行的操作”而是利用编译时保存的调试信息、栈帧信息和相关状态恢复正确的执行位置与必要状态。部分已完成的程序操作不能简单地被重新执行一遍否则可能产生重复副作用。学习总结JIT 的推测性优化不是忽略正确性约束而是将部分条件交给运行时检查。当条件失效时通过去优化等机制回到正确的执行路径。2. 栈上替换OSROSR 的全称是 On-Stack Replacement即栈上替换。考虑以下情况staticlongcalculate(longn){longsum0;// 方法只调用一次但循环可能执行很多次。for(longi0;in;i){sumi;}returnsum;}如果 JVM 等到calculate返回后才处理编译问题就无法及时优化一个正在长时间运行的热点循环。OSR 允许 JVM 为热点循环生成适当的编译入口使正在解释执行的活动方法可以在满足条件时转入编译代码而不必等到整个方法调用结束后再从头开始。OSR 既体现了 JVM 以方法和循环热点为依据的优化思想也涉及解释帧、编译帧之间的状态衔接。实际发生 OSR 需要满足编译策略及具体实现条件并非每个热点循环都必然成功执行 OSR。八、从系统工程师角度验证上述结论理解源码之后还需要通过实际运行数据验证执行模型避免只凭理论推断性能。1. 查看字节码javac BytecodeDemo.java javap-c-vBytecodeDemo重点观察方法的Code属性、字节码指令、操作数栈最大深度、局部变量信息和异常表。对于需要进一步研究的方法还可以核对方法描述符及常量池引用。2. 观察编译事件java-XX:PrintCompilationBytecodeDemoPrintCompilation可以帮助观察方法是否发生编译、编译级别及相关编译事件。但输出中出现一个方法并不意味着已经掌握其全部优化细节。若希望进一步观察内联决策可在支持这些诊断选项的 HotSpot 构建上使用java-XX:UnlockDiagnosticVMOptions\-XX:PrintCompilation\-XX:PrintInlining\BytecodeDemo这些选项主要用于观察与诊断不应直接作为正式性能测试的标准配置。运行时参数及输出格式可能随 JDK 版本发生变化。3. 比较解释执行与编译执行可以通过以下模式辅助研究# 仅使用解释器适合研究解释执行路径java-XintBytecodeDemo# 允许通常的分层编译行为javaBytecodeDemo# 强制积极采用编译执行策略仅适合诊断和实验java-XcompBytecodeDemo-Xcomp不等价于真实生产环境中的稳定热点编译过程不应该简单地用它与默认模式的运行时间差来判断 JIT 的最终收益。要比较性能应设计可重复的基准测试考虑启动时间、预热、垃圾回收、编译耗时、CPU 频率变化以及程序输入分布等因素。对于更深入的分析可以进一步研究OpenJDK 的compileBroker.cpp编译任务如何进入编译系统。OpenJDK 的compilationPolicy.hpp执行级别如何转换以及热点策略如何受队列负载影响。OpenJDK 的opto/parse1.cppC2 如何解析方法并建立中间表示。OpenJDK 的runtime/deoptimization.cpp如何处理编译代码退出和执行状态恢复。以上源码链接均指向 OpenJDK 主线实际学习时应切换到与目标运行环境相匹配的 JDK 标签或提交版本。九、最终学习总结从系统工程师的角度解释器和 JIT 的区别不仅是“一个解释、一个编译”更重要的是它们在 JVM 执行体系中承担的职责不同。解释器根据 JVMS 规定的指令语义执行字节码维护方法执行状态并为运行时剖析和热点检测提供基础。JIT 编译器通过分析热点方法或循环将字节码转换为中间表示并结合静态信息与运行时反馈进行优化最终生成 CPU 可直接执行的本地机器码。HotSpot 运行时系统负责在解释执行、不同编译级别、OSR 和去优化等路径之间进行协调使程序能够在正确性约束下利用运行时信息提高执行效率。学习时建议牢牢抓住三条主线第一JVMS 规定了哪些语义不可改变第二HotSpot 通过哪些解释器及编译器实现这些语义第三运行时计数、编译队列、机器码安装和去优化如何共同影响程序真实的执行性能。这三条主线贯通之后就能从“理解某条 JVM 字节码”进一步深入到“理解某段 Java 代码在真实 JVM 和 CPU 上为何这样运行”。十、解释器与 JIT 编译器的源码对照总结为了把规范与实现对应起来建议采用“规范条款 → Java 示例 → 字节码 → HotSpot 源码 → 运行时验证”的学习方法。1. 规范层与实现层的区别对比维度JVMS 规范HotSpot 实现执行对象JVM 字节码字节码、解释器代码、中间表示和本地机器码执行模型定义指令语义、栈帧和控制流可以使用模板解释器及 JIT性能优化允许实现采用不同优化方法根据运行时剖析和编译策略进行优化执行代码不规定必须采用某种形式可执行解释器生成的机器码或 JIT 编译后的机器码优化假设失效要满足规范要求的行为可借助保护检查、去优化等机制恢复正确执行JVMS 明确将很多内部实现细节留给具体的 JVM 实现包括将字节码翻译成本地机器码。2. 推荐的源码阅读顺序第一阶段理解规范阅读 JVMS 第 2 章JVM 结构 与 第 6 章指令集。重点Frame、局部变量表、操作数栈、指令语义与控制流。第二阶段分析解释器阅读 templateTable.cpp、templateInterpreterGenerator.cpp。重点字节码处理模板、解释器入口和指令分派。第三阶段分析 JIT 编译阅读 compilationPolicy.hpp、compileBroker.cpp 与 parse1.cpp。重点热点判断、编译任务调度与 C2 字节码解析。第四阶段分析执行状态转换阅读 deoptimization.cpp。重点优化假设失效时如何恢复解释执行所需的状态。3. 最小实验验证字节码与编译行为下面给出一个可直接编译运行的 Java 示例。代码中的注释说明了需要重点观察的行为。publicfinalclassBytecodeDemo{// 研究目标理解 iload、iadd、ireturn 三条指令的语义。staticintsum(inta,intb){returnab;}publicstaticvoidmain(String[]args){longchecksum0;// 高频调用为 JIT 热点检测和优化提供观察对象。for(inti0;i10_000_000;i){checksumsum(i,1);}System.out.println(checksum);}}先查看字节码javac BytecodeDemo.java javap-c-vBytecodeDemosum方法的核心字节码应类似于iload_0 // 将参数 a 加载到操作数栈 iload_1 // 将参数 b 加载到操作数栈 iadd // 弹出两个 int执行加法再将结果压栈 ireturn // 返回 int 结果再观察实际编译事件# 观察常规 JVM 执行及编译行为java-XX:PrintCompilationBytecodeDemo# 在支持相应诊断选项的 HotSpot 上观察内联决策java-XX:UnlockDiagnosticVMOptions\-XX:PrintCompilation\-XX:PrintInlining\BytecodeDemo还可以用以下模式进行辅助对照# 以解释器执行为主研究解释路径java-XintBytecodeDemo# 积极采用编译执行策略适合诊断实验java-XcompBytecodeDemo实验时需要注意sum可能被内联因而不能期待始终看到一个独立的sum机器码调用。-Xcomp也不等价于默认分层编译下经过充分预热的生产运行状态。正式性能比较应控制预热、输入、垃圾回收及测试环境。十一、最终结论解释器解决的是“如何执行字节码”JIT 编译器解决的是“如何让热点字节码更高效地执行”。解释器按照 JVM 指令语义执行操作并维护运行时执行状态JIT 则通过解析字节码、构建中间表示、应用优化和生成机器码减少热点代码的重复解释开销。HotSpot 还通过热点检测、分层编译、OSR 和去优化等机制协调执行效率与程序语义正确性。作为系统工程师最重要的不是机械记忆某一条字节码对应哪条 CPU 指令而是能够从真实源码和运行数据回答三个问题为什么这段字节码这样执行、JIT 为什么认为这段代码值得优化以及优化前后 JVM 如何继续保证正确的执行语义。
RELATED

相关推荐

超级具身智能“感知-决策中枢”研究(4):基于模型的小样本策略收敛机理研究

超级具身智能“感知-决策中枢”研究(4):基于模型的小样本策略收敛机理研究

前沿技术探索:FRA核心定义与设计理念FRA(Factorized Robotic Agent, FRA,亦称:因式分解机器人智能体)是一套因式化数实融合一体化新型智能系统,核心设计理念是全链路系统解耦,将机器人作业的感知…

📅 2026/10/30 6:45:01
钢化玻璃隔断:办公室与家装空间分区优选

钢化玻璃隔断:办公室与家装空间分区优选

现在不管是办公室装修,还是家里改造分区,很多人都会纠结隔断怎么选。做隔断既要划分好空间,又不想把屋子隔得压抑,还要考虑日常使用的安全问题,钢化玻璃隔断,就是一个很稳妥的方案。 灰色隔断效果 很多人喜…

📅 2026/10/30 6:40:01
Swift-1.5-Qwen3.8-27B-GGUF 快速上手:如何用 llama.cpp 三步跑起来本地部署

Swift-1.5-Qwen3.8-27B-GGUF 快速上手:如何用 llama.cpp 三步跑起来本地部署

Swift-1.5-Qwen3.8-27B-GGUF 快速上手:如何用 llama.cpp 三步跑起来本地部署 Swift-1.5-Qwen3.8-27B-GGUF 是 UkisAI 推出的推理高效模型 Swift 1.5 Qwen3.8-27B 的 GGUF 量化版,专为 llama.cpp 本地部署设计。它比基座模型少用 58.5% 的思考 token&…

📅 2026/10/30 6:40:01
MORE NEWS

更多资讯

📰

LoRa自组网三大路线对比:洪泛、路由与网络栈如何选型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

ESP32 NVS浏览器编辑器:零烧录修改WiFi密码

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

从水闸到CMOS:手造8位ALU理解CPU底层逻辑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

基于BLE低功耗蓝牙的维修钥匙方案设计与功耗优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

MATLAB多特征融合稻叶病识别:颜色纹理形状融合与SVM分类实战

简介:本资源为基于Matlab开发的多特征融合稻叶病图像识别系统完整源码,面向农业信息化、图像识别方向的本科生与研究生,以及参加科创竞赛的开发者。系统以颜色特征分割提取病斑区域,融合颜色、形状、纹理等多维特征,采…

📰

工程管理软件行业趋势与选型实施指南

1. 工程管理软件行业现状与2026年趋势展望当前国内工程管理软件市场正处于高速发展期,随着建筑行业数字化转型加速,2023年市场规模已突破200亿元,年复合增长率保持在15%以上。从应用场景来看,头部解决方案已覆盖工程项目全生命周期…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬