钱争 發表於 2025-9-2 20:34:00

JVM的组成部分

<p>我们先说说 <strong>JVM&nbsp;</strong>是什么,Java Virtual Machine(Java 虚拟机)。我们可以把它理解成一个 "虚拟的计算机" —— 它不是真实的硬件设备,而是一段能运行 Java 字节码的程序。</p>
<p>如果 Java 代码是 "世界通用的食谱",那么 JVM 就是 "能看懂这份食谱的厨师"。不管是用&nbsp;Windows 、Mac 还是 Linux,只要安装了对应平台的 JVM,就能把同一份 Java 字节码(.class 文件)"做"&nbsp;出同样的效果。这也是 Java 能实现 "<strong>一次编写,到处运行</strong>(<strong>Write Once, Run Anywhere</strong>)"&nbsp;的核心秘密。</p>
<h4>1、类加载子系统(ClassLoader Subsystem)</h4>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) </strong>定义:负责把 <strong><code>.class</code></strong> 文件加载到 JVM 内存中。</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <strong>(2)</strong> 主要步骤:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>①</strong>&nbsp;<strong>加载(Loading)</strong>:从文件系统或网络中找到 class 文件,读进内存。</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>②</strong>&nbsp;<strong>链接(Linking)</strong>:验证(字节码是否安全)、准备(为类变量分配内存并设置默认值)、解析(将符号引用转为直接引用)。</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <strong>③</strong>&nbsp;<strong>初始化(Initialization)</strong>:执行类变量的赋值操作和静态代码块。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>(3)&nbsp;</strong>主要的类加载器:启动类加载器(Bootstrap)、扩展类加载器(Extension)、应用类加载器(Application)。</p>
<h4>2、运行时数据区(Runtime Data Area)</h4>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JVM 在&nbsp;<strong>运行</strong> Java 程序时使用的内存区域,可以分为:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>(1)&nbsp;方法区(Method Area)</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①</strong>&nbsp;存储类相关信息(类的结构、方法、字段、常量池)。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②</strong>&nbsp;在 HotSpot JVM 中,早期叫 <strong>永久代(PermGen)</strong>,后期改为 <strong>元空间(Metaspace)</strong>。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;堆(Heap)</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①&nbsp;</strong>存放所有对象实例。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②&nbsp;</strong>是垃圾回收器(GC)的主要工作区域。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;③&nbsp;</strong>通常分为 <strong>新生代(Young Generation)</strong>和 <strong>老年代(Old Generation)</strong>。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3)&nbsp;Java 虚拟机栈(JVM Stack)</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①&nbsp;</strong>每个线程启动时都会创建一个栈。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②&nbsp;</strong>用来存储方法调用时的 <strong>局部变量、操作数栈、返回地址</strong> 等信息。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;③&nbsp;</strong>每次方法调用就是一个 <strong>栈帧</strong>。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4)&nbsp;本地方法栈(Native Method Stack)</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①&nbsp;</strong>与 JVM Stack 类似,但服务于 <strong>本地方法(Native Method)</strong>。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②&nbsp;</strong>通常是用 C/C++ 实现的。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(5)&nbsp;程序计数器(Program Counter, PC Register)</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①&nbsp;</strong>每个线程都有一个独立的程序计数器。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②&nbsp;</strong>保存当前线程正在执行的字节码的地址。</p>
<h4>3、执行引擎(Execution Engine)</h4>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;</strong>负责把字节码 <strong>解释/编译</strong> 为机器指令,交给底层操作系统执行。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;</strong>主要包括:</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①&nbsp;解释器</strong>:逐行解释执行字节码。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;②&nbsp;JIT 编译器(Just-In-Time Compiler)</strong>:将热点代码编译成本地机器码,提高执行效率。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;③&nbsp;即时编译优化组件</strong>:对热点代码进行优化,例如方法内联、循环展开等。</p>
<h4>4、本地方法接口(JNI, Java Native Interface)</h4>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1)&nbsp;</strong>提供 Java 调用其他语言(如 C、C++)库的能力。</p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)&nbsp;</strong>通过 JNI,可以让 Java 程序访问底层操作系统或硬件功能。</p>
<p>我看有网友问&nbsp;<strong>垃圾回收器</strong> 算不算JVM的一部分呢?垃圾回收 并不是 JVM 的 "组成模块",而是 <strong>JVM 的一项功能</strong>。不同 JVM 提供了不同的 <strong>GC </strong>实现,比如 CMS、G1、ZGC 等。</p>
<p style="text-align: right"><span style="color: rgba(53, 152, 219, 1)">真正的强者,不是不失败,而是善于从失败中吸取教训。-- 烟沙九洲</span></p><br><br>
来源:https://www.cnblogs.com/yanshajiuzhou/p/19070685
頁: [1]
查看完整版本: JVM的组成部分