服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-11-11 简米科技 2,766 字 6 分钟阅读

Java虚拟机执行流程是怎样的?,JVM类加载到卸载流程是什么?

导读从一次Java方法调用说起Java虚拟机的执行流程是一条从字节码加载、校验、解析、初始化到执行、优化、回收、卸载的完整链路,核心机制可概括为“类加载子系统负责把.class文件搬进内存,执行引擎负责把字节码变成机器指令,运行时数据区负责在中间承接所有活数据”,如果把JVM比作一家工厂,类加载器就是原料采购部门……

从一次Java方法调用说起

Java虚拟机的执行流程是一条从字节码加载、校验、解析、初始化到执行、优化、回收、卸载的完整链路,核心机制可概括为“类加载子系统负责把.class文件搬进内存,执行引擎负责把字节码变成机器指令,运行时数据区负责在中间承接所有活数据”。

如果把JVM比作一家工厂,类加载器就是原料采购部门,执行引擎是车间里的老技工,垃圾回收器则是负责清场和回收报废零件的后勤组,整条链路环环相扣,任何一个环节卡住,程序就会原地罢工,下面顺着原料进厂到成品报废的顺序,把这套流程拆开来看。

Java虚拟机执行流程和JVM内存模型的区别在哪?

业内专家指出,这两个概念经常被混着说,其实分工差别很大,执行流程讲的是“时间线上的动作”:类怎么进来、字节码怎么被翻译、方法怎么被调用、对象怎么被回收,JVM内存模型讲的是“空间上的布局”:方法区、堆、虚拟机栈、本地方法栈、程序计数器各放什么,执行流程是动词,内存模型是名词,理解执行流程,必须先把运行时数据区当作舞台背景,否则字节码在哪儿跑、栈帧怎么压都说不清楚。

从.class到机器码:JVM类加载过程面试题常考环节

JVM类加载过程面试题出现频率很高,核心就三个阶段:加载、链接、初始化。

  • 加载:类加载器根据全限定名找到.class文件,读成一个二进制字节流,然后在方法区生成这个类的运行时数据结构,在堆里生成一个Class对象作为访问入口。
  • 链接:分三步走,验证阶段检查字节码格式、语义、符号引用是否合法,防止恶意代码混进来;准备阶段给静态变量分配内存并设零值,注意是零值,不是代码里写的初始值;解析阶段把常量池里的符号引用替换成直接引用。
  • 初始化:执行类构造器<clinit>(),给静态变量赋真实值,跑静态代码块,这一步由JVM保证线程安全,父类先于子类初始化。

面试里常会追问双亲委派模型,启动类加载器、扩展类加载器、应用类加载器层层向上问,先让父加载器尝试,父加载器加载不了才自己动手,这样做的目的是保证核心类库不被篡改。

实操验证可以用javap看字节码:

javap -v -p Hello.class

输出里能看到常量池、方法签名和<clinit>的位置,想看类加载过程可以加参数:

java -verbose:class -cp . Hello

JVM字节码执行引擎工作原理详解

字节码进内存之后,真正干活的是执行引擎,它有两种工作模式:解释执行和即时编译。

解释执行像逐字逐句读稿子,读一条字节码执行一条,启动快但长期跑效率一般。即时编译把热点代码翻译成本地机器码再执行,运行效率高,但编译本身要花时间和内存,行业共识认为,现代JVM默认走混合模式:先解释执行,跑一会儿统计到热点方法后触发JIT编译,把热代码换成机器码,分层编译进一步把JIT分成C1和C2,C1编译快、优化少,C2编译慢、优化深,两者配合兼顾启动和峰值性能。

执行方法时,JVM会在当前线程的虚拟机栈里压入一个栈帧,结构包括:

  • 局部变量表:放方法参数和局部变量,以变量槽为单位分配。
  • 操作数栈:执行字节码时临时存取数据,压栈弹栈。
  • 动态链接:指向运行时常量池中该方法的符号引用。
  • 方法返回地址:记录方法执行完后回到哪。

方法调用有解析和分派两条路,静态方法、私有方法、构造器这类在编译期就能确定版本的,走解析,普通实例方法走动态分派,根据调用者的实际类型在方法区里查虚方法表。invokedynamic则是给Lambda和动态语言用的,把调用点绑定延迟到运行时。

想看JIT编译情况可以打开编译日志:

java -XX:+PrintCompilation -cp . Hello

输出会逐行显示哪些方法被编译、用了哪层编译器。

JVM对象从加载到卸载的完整过程

对象的一生从new开始,到GC判断不可达结束,沿时间线看:

  1. 类加载完成后,执行new指令时JVM在堆里分配内存,常用指针碰撞或空闲列表两种方式。
  2. 分配完内存设零值,再执行构造方法完成初始化。
  3. 对象从新生代Eden区开始,经过Minor GC存活后进入Survivor区,年龄够大或Survivor装不下时晋升老年代。
  4. 老年代发生Full GC时若对象仍不可达,被回收。

卸载比回收更严格,类卸载要同时满足三个条件:该类所有实例都被回收、加载该类的ClassLoader被回收、该类的Class对象没有引用,多数情况下只有自定义类加载器加载的类才有机会卸载,系统类加载器加载的核心类基本常驻。

JVM卸载类加载器和卸载类的区别是什么?

这两个动作经常被合并理解,但顺序和条件不同。

对比项 卸载类加载器 卸载类
触发条件 加载器实例不可达,被GC回收 类实例全回收、ClassLoader被回收、Class对象无引用
影响范围 该加载器加载的所有类一起失去归属 单个类的元数据从方法区清除
常见场景 OSGi、热部署、插件容器 动态生成类、反射生成的临时类
系统类加载器 基本不卸载 基本不卸载

可以理解为:加载器是“户口本”,类是“户口本上的成员”,户口本销毁了,上面的成员自然就没了;单独把一个成员迁走,户口本还在,热部署框架能做到代码热替换,靠的就是用新的自定义类加载器重新加载类,旧加载器连同旧类一起被回收。

观察类卸载可以加参数:

java -XX:+TraceClassUnloading -cp . Hello

Q&A:关于Java虚拟机执行流程的常见追问

Q:Java虚拟机执行流程中类加载和对象创建是同一回事吗?
A:不是,类加载是把类的元数据搬进方法区、在堆里生成Class对象,属于类级别的一次性动作,对象创建是在类加载完成后,执行new时在堆里分配实例内存并初始化,属于实例级别、可重复发生的动作。

Q:字节码为什么不直接翻译成机器码,还要经过解释执行这一层?
A:解释执行是启动阶段的低成本方案,如果全部靠JIT编译,启动时编译开销大、内存占用高,短生命周期程序会得不偿失,混合模式让程序一边跑一边收集热点信息,把编译资源花在真正高频的方法上,整体性价比更高。

Q:Java虚拟机执行流程和垃圾回收是什么关系?
A:垃圾回收是执行流程里的后勤环节,字节码执行过程中不断创建对象、方法返回后栈帧弹出,堆里的对象逐渐变为不可达,GC根据可达性分析找出这些对象并回收,回收后类加载器若也不可达,类才可能进入卸载阶段,整条流程从加载到卸载,GC始终在后半程承上启下。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱