网易首页 > 网易号 > 正文 申请入驻

JVM运行内幕:7步拆解字节码到机器码

0
分享至

你写的每一行Java代码,从保存文件到真正跑起来,中间隔着7个精密环节。理解它们,才能解释为什么你的服务启动慢、为什么内存会炸、为什么同样的代码第二次运行更快。

编译:从人话到字节码


javac 做的不是"翻译",而是"降维"。

它把你的Java源码变成字节码(bytecode)——一种平台无关的中间格式,存成 .class 文件。这些文件可以打包进JAR,或者按Java 9之后的模块系统组织。

关键认知:字节码不是机器码。它跑不了,只能被JVM"解释"或"编译"后才能执行。这是Java"一次编写,到处运行"的根基,也是性能争议的源头。

加载:类加载器的层级博弈

类加载器子系统采用双亲委派模型(parent delegation)。不是"先自己找",而是"先问爸爸"。

三层分工:

启动类加载器(Bootstrap):加载JDK核心类,java.lang.* 这些。用C++实现,Java代码里看不见。

平台类加载器(Platform):加载扩展类,JDK的 lib/ext 目录或模块路径。

系统类加载器(System):加载你的应用代码,CLASSPATH指定的那些。

为什么要"先问爸爸"?安全。防止你写一个 java.lang.String 把JDK的替换掉。也防止重复加载——父加载器加载过的,子加载器不再加载。

但打破双亲委派也有场景。Tomcat给每个Web应用独立类加载器,就是为了让同名的Servlet类可以隔离共存。OSGi、SPI机制(Service Provider Interface)也是破坏者。

链接:验证、准备、解析

类加载进来后,进入链接阶段,三步走:

验证(Verify):JVM检查字节码是否合法。操作数栈不会溢出、类型转换安全、跳转指令不越界。这是安全沙箱的第一道防线。

准备(Prepare):为类的静态变量分配内存,并赋予默认值static int count = 10,这时候 count = 0。真正的10还没来。

解析(Resolve):把符号引用变成直接引用。你的代码里写 new UserService(),编译后是个字符串符号。解析阶段找到UserService类在内存里的实际地址,把指针填进去。

解析可以延迟。用到的时候才解析,节省启动时间。

初始化:静态世界的诞生

这是类加载的最后一步,也是程序员最能感知的一步。

静态变量被赋予真正的初始值,static 代码块按顺序执行。这个过程是线程安全的——JVM保证一个类的初始化只会发生一次,多线程竞争时只有一个能执行,其他的阻塞等待。

触发初始化的时机:new实例、访问静态变量/方法、反射调用、子类初始化触发父类初始化、main方法所在类。被动引用不会触发,比如只定义父类的静态字段引用。

很多"诡异"的类加载问题,根源在这里。循环依赖的静态初始化、静态块里的耗时操作,都会在这一步暴露。

内存布局:线程共享与隔离

JVM内存不是一块大平地,而是严格分区的建筑。

线程共享区:

堆(Heap):所有对象实例和数组。GC的主战场。新生代、老年代、永久代/元空间,都在这里。

方法区(Method Area):类信息、常量池、静态变量、JIT编译后的代码缓存。JDK 8之前叫永久代(PermGen),之后叫元空间(Metaspace),移到了本地内存。

线程私有区:

JVM栈(Stack):每个线程一个栈,栈帧对应方法调用。局部变量表、操作数栈、动态链接、方法返回地址。

程序计数器(PC Register):当前线程执行的字节码行号指示器。线程切换时靠它恢复位置。

本地方法栈(Native Method Stack):给JNI调用的C/C++方法用的栈。

直接内存(Direct Memory)不在JVM规范里,但NIO的 ByteBuffer.allocateDirect 用它。绕过堆,减少一次拷贝,但不受GC直接管理,容易内存泄漏。

执行引擎:解释与编译的拉锯战

字节码终于要被"执行"了。JVM有两种武器:

解释器(Interpreter):逐条读字节码,边解释边执行。启动快,执行慢。适合跑一两次的代码。

JIT编译器(Just-In-Time Compiler):把热点代码编译成本地机器码,存到代码缓存(Code Cache)。后续直接执行机器码,速度接近C++。但编译本身耗时,触发需要"预热"。

热点检测基于方法调用计数器回边计数器。方法被调用多少次,循环执行多少轮,达到阈值就进编译队列。

C1编译器(Client Compiler):快速编译,优化少,适合桌面应用快速启动。C2编译器(Server Compiler):深度优化,激进编译,适合服务端长期运行。Java 7引入的分层编译(Tiered Compilation),先C1后C2,平衡启动和峰值性能。

Graal编译器是C2的替代者,用Java写编译器,支持AOT(Ahead-Of-Time)编译,让Java也能像Go一样快速冷启动。

垃圾回收:自动化的代价与选择

堆内存的回收是JVM最复杂的子系统。对象存活判定、回收算法、收集器实现,决定了你的服务是丝滑还是卡顿。

判定算法:

引用计数:Python用,JVM不用。循环引用解决不了。

可达性分析:从GC Roots(栈帧局部变量、静态变量、常量、JNI引用等)出发,能走到的对象存活,走不到的回收。

回收算法:

标记-清除(Mark-Sweep):先标记存活,再清除死亡。碎片多。

复制(Copying):内存分两半,存活对象复制到另一半,整片清空。无碎片,但内存利用率50%。新生代用这个,因为大部分对象朝生夕死,复制成本低。

标记-整理(Mark-Compact):标记后把存活对象往一端移动,清理边界外。老年代用这个,对象存活率高,复制不划算。

收集器演进:

Serial/Serial Old:单线程,STW(Stop-The-World)长。现在只配做客户端默认。

Parallel/Parallel Old:多线程并行,吞吐优先。JDK 8默认。

CMS(Concurrent Mark Sweep):并发低停顿,但碎片严重,JDK 14已移除。

G1(Garbage First):Region化内存,预测停顿时间,平衡吞吐和延迟。JDK 9+默认。

ZGC/Shenandoah:亚毫秒级停顿,TB级堆,染色指针、读屏障。JDK 15+生产可用。

选收集器不是越新越好。ZGC的吞吐量比G1低10%-20%,如果你的服务是批处理而非在线服务,可能反而更慢。

本地接口:JNI的双刃剑

Java代码调用C/C++库,走Java本地接口(JNI,Java Native Interface)。

流程:Java声明native方法 → 生成头文件 → C/C++实现 → 编译成动态链接库 → System.loadLibrary加载。

JNI打破了JVM的安全边界。C代码的内存泄漏、段错误,会直接搞崩整个JVM进程。字符串、数组在JNI里要手动管理内存,Get/Release配对。局部引用表有限,大量对象要及时DeleteLocalRef。

Netty的零拷贝、TensorFlow Java API、各种数据库驱动,底层都依赖JNI。用得好是性能利器,用不好是稳定性的噩梦。

实战:从启动慢到诊断工具链

理解JVM结构后,常见的性能问题有了排查路径。

启动慢:检查类加载数量(-verbose:class),看是不是加载了太多jar。用AppCDS(Application Class-Data Sharing)把类元数据缓存到文件,下次直接映射,省掉解析验证。

内存溢出:堆溢出看对象存活周期,用MAT(Memory Analyzer Tool)分析dump文件。元空间溢出检查动态生成类(CGLIB、反射)是否泄漏。直接内存溢出,看NIO的Buffer有没有手动释放。

卡顿:打印GC日志(-Xlog:gc*),看STW时间。用async-profiler做火焰图,定位热点方法。JIT编译本身也会暂停,C2编译复杂方法时的去优化(deoptimization)可能引发抖动。

工具链:

jps:看Java进程

jstat:监控GC、类加载、编译统计

jmap:生成堆dump

jstack:打印线程栈

arthas:阿里巴巴开源,在线诊断,反编译、热更新、trace方法耗时

JFR(Java Flight Recorder):低开销持续记录,JDK商业特性开源后的利器

为什么这7步值得刻进脑子

云原生时代,JVM的"重"被反复诟病。启动慢、内存大、容器里表现诡异。

但理解这7步,你会发现优化空间:

• GraalVM的AOT编译,把初始化阶段提前到构建时,冷启动进到毫秒级

• CRIU(Checkpoint/Restore In Userspace)冻结预热后的JVM状态,恢复时跳过前面6步

• Quarkus、Micronaut框架,编译期做依赖注入,减少运行时反射和类加载

JVM不是黑箱。从字节码到机器码的旅程,每一步都有设计取舍,也都有调优杠杆。下次面试被问到"对象怎么创建的"、线上遇到"Metaspace OOM"、争论"Java到底慢不慢",这7步就是你的底层操作系统。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
蔚来回应ES9仍用隐藏式门把手:目前蔚来全系在售车型,均可以正常使用隐藏式门把手,也完全合规

蔚来回应ES9仍用隐藏式门把手:目前蔚来全系在售车型,均可以正常使用隐藏式门把手,也完全合规

鲁中晨报
2026-04-18 17:16:31
罚15亿!拼多多一员工故意关门,对抗调查,导致执法人员手指骨折

罚15亿!拼多多一员工故意关门,对抗调查,导致执法人员手指骨折

魔都姐姐杂谈
2026-04-19 08:03:27
马龙许昕驰援成都陪练全网刷屏:我一点都不感动,反而后背发凉……

马龙许昕驰援成都陪练全网刷屏:我一点都不感动,反而后背发凉……

最爱乒乓球
2026-04-19 00:05:11
教育部刚通知!9月起上学新规全覆盖,普通家庭孩子上学迎公平

教育部刚通知!9月起上学新规全覆盖,普通家庭孩子上学迎公平

复转这些年
2026-04-18 11:43:46
面多加水,水多加面?外媒痛批:电车3吨重,填鸭式造车不可取!

面多加水,水多加面?外媒痛批:电车3吨重,填鸭式造车不可取!

少数派报告Report
2026-04-17 07:03:05
何润东谈张凌赫被评价“粉底液将军”:不一样的戏种、类型,是完全不能比较的;称自己翻红后接到很多工作邀约,还没时间看《逐玉》

何润东谈张凌赫被评价“粉底液将军”:不一样的戏种、类型,是完全不能比较的;称自己翻红后接到很多工作邀约,还没时间看《逐玉》

鲁中晨报
2026-04-17 09:24:06
潘石屹两次蛐蛐许家印

潘石屹两次蛐蛐许家印

哲空空
2026-04-19 11:07:10
蔡磊妻子段睿半夜悲痛发文:明知没有机会了,偏要赌他会等我回来

蔡磊妻子段睿半夜悲痛发文:明知没有机会了,偏要赌他会等我回来

乐天闲聊
2026-04-19 07:05:22
欧洲没料到,竟有国家和中国订下军购大单?包括红旗-9和歼-10

欧洲没料到,竟有国家和中国订下军购大单?包括红旗-9和歼-10

易昂杨
2026-04-19 09:36:56
英媒批评赵心童半场表现:看起来一点不自在,总让自己处在危险中

英媒批评赵心童半场表现:看起来一点不自在,总让自己处在危险中

杨华评论
2026-04-18 21:40:51
泰国泼水节死亡人数为何居高不下?交通事故频发,6年来平均每年200多人遇难,被称为“危险七日”

泰国泼水节死亡人数为何居高不下?交通事故频发,6年来平均每年200多人遇难,被称为“危险七日”

极目新闻
2026-04-19 10:56:08
管泽元口无遮拦 “大高个就得玩女明星”引爆舆论

管泽元口无遮拦 “大高个就得玩女明星”引爆舆论

游民星空
2026-04-17 23:03:56
厂妹的生活

厂妹的生活

微微热评
2026-04-19 09:02:11
苏超积分榜一夜变天!徐州3球血洗泰州,宿迁掀翻南京,常州领跑

苏超积分榜一夜变天!徐州3球血洗泰州,宿迁掀翻南京,常州领跑

陈秣爱钓鱼
2026-04-19 03:53:03
拔萝卜带泥!逃往美国的恒大“二把手”,邻居却是另一名潜逃富豪

拔萝卜带泥!逃往美国的恒大“二把手”,邻居却是另一名潜逃富豪

二大爷观世界
2026-03-14 18:43:53
男子抓住跳楼的女友,5分钟后力竭女友坠楼身亡,法院:男子疏于照看存在过错,已尽力施救,承担10%责任

男子抓住跳楼的女友,5分钟后力竭女友坠楼身亡,法院:男子疏于照看存在过错,已尽力施救,承担10%责任

鲁中晨报
2026-04-18 07:28:17
全网唱衰的下嫁!嫁普通人5年,前任是法拉利总裁,终究还是输了

全网唱衰的下嫁!嫁普通人5年,前任是法拉利总裁,终究还是输了

橙星文娱
2026-04-18 16:42:58
研究表明,中学生的抑郁率已高达36%!

研究表明,中学生的抑郁率已高达36%!

黯泉
2026-04-18 18:06:01
四艘中资超级油轮顺利通过美军封锁区引发强烈冲击

四艘中资超级油轮顺利通过美军封锁区引发强烈冲击

阿尔法34号
2026-04-19 07:04:28
雷军宣布:小米车主安全行驶里程达十万公里,可获赠实体限量徽章、精美虚拟勋章,一键生成专属行车故事

雷军宣布:小米车主安全行驶里程达十万公里,可获赠实体限量徽章、精美虚拟勋章,一键生成专属行车故事

鲁中晨报
2026-04-18 16:20:17
2026-04-19 12:35:00
闪存猎手
闪存猎手
全网蹲好价的野生捕手,算力与羊毛都不可辜负。
1521文章数 13关注度
往期回顾 全部

科技要闻

50分26秒破人类纪录!300台机器人狂飙半马

头条要闻

牛弹琴:伊朗遭到特朗普"羞辱"被激怒 结果印度遭了殃

头条要闻

牛弹琴:伊朗遭到特朗普"羞辱"被激怒 结果印度遭了殃

体育要闻

掘金擒狼开门红:五花肉与小辣椒

娱乐要闻

张天爱评论区沦陷!被曝卷入小三风波

财经要闻

华谊兄弟,8年亏光85亿

汽车要闻

29分钟大定破万 极氪8X为什么这么多人买?

态度原创

教育
家居
旅游
数码
本地

教育要闻

出国留学的人多少回国了?

家居要闻

法式线条 时光静淌

旅游要闻

太原直飞莫斯科旅游包机复航

数码要闻

联想ThinkPlus 190W移动电源开售,售价349元

本地新闻

12吨巧克力有难,全网化身超级侦探添乱

无障碍浏览 进入关怀版