JVM的体系结构、类加载器及双亲委派机制

JVM 体系结构 🔧🏗️

JVM(Java 虚拟机)可以被看作一个运行 Java 程序的工厂🏭,而这个工厂有几个主要部门,各司其职,让程序顺利运行。我们可以把 JVM 体系结构分为三个核心部分:类加载子系统运行时数据区执行引擎。每个部分都有它的独特职责。🤓📚

1. 类加载子系统(Class Loader Subsystem)🛠️

想象一下,你要做一道菜🍝,首先需要准备食材对吧?这个“类加载子系统”就是负责把你写的 Java 类(比如:HelloWorld.class)加载到 JVM 中,就像把所有的食材搬到厨房一样。

  • 工作方式:JVM 会通过类加载器找到并加载需要的 Java 类。首先会找到 .class 文件,然后把它加载到内存中准备执行。
2. 运行时数据区(Runtime Data Area)🗂️🧠

这里可以看作是 JVM 的“大脑”,负责管理和存储程序运行时所需的数据。想象一下你在做菜时需要用到不同的锅、碗、盘子🛒——这些工具就是 JVM 的内存区域,每个部分都有不同的功能。

  • 堆(Heap):用来存储所有的对象和实例。就像你在厨房的冰箱里存放食材🍎🥦,所有的对象都放在这里。
  • 栈(Stack):保存局部变量和方法调用。就像你做菜时用的刀具和锅具,它们都是临时用完就会放回去的🔪🍳。
  • 方法区(Method Area):存储类结构、方法数据以及静态变量。这个就像你厨房的菜单📝,告诉你有哪些菜(类)以及这些菜怎么做(方法)。
  • 程序计数器(Program Counter, PC):负责记录当前执行到哪一行代码了,像是你的烹饪指南📖,告诉你下一步该做什么。
  • 本地方法栈(Native Method Stack):如果你的程序中用了其他语言(比如 C 或 C++),这里就是帮你运行这些本地代码的区域,就像你借用其他厨师的工具来帮你做菜🧑‍🍳。
3. 执行引擎(Execution Engine)🚀

现在你已经把食材准备好了,锅碗瓢盆都齐了,现在需要有人来烹饪对吧?执行引擎就是那个真正负责“做饭”的厨师👨‍🍳!它会根据你写的代码,把这些数据转换成机器可以理解的指令,让程序顺利运行。

  • 解释器(Interpreter):逐行解释字节码(像是食谱📖),一行一行执行代码。
  • 即时编译器(JIT Compiler):如果某些代码执行得特别频繁,JIT 会把这些代码直接编译成机器码,这样后续运行速度会更快!相当于提前准备好了一些食材,减少了重复劳动💨。

类加载器(Class Loader)🛠️🍕

类加载器就像厨房里的食材搬运员🍲,负责把你需要的“食材”(Java 类文件)搬进来,让 JVM 能处理这些类。每当你在 Java 里写一个类,JVM 都需要先找到这些类文件并加载到内存里才能执行。类加载器就是干这个活儿的。

类加载器的三种类型 🚚🔍

JVM 有三种常见的类加载器,想象它们是负责搬运不同层次的“食材员”:

  1. 启动类加载器(Bootstrap ClassLoader) 🏗️
    • 它是大厨手下最有经验的搬运工💪,负责搬运最基础的食材,比如 Java 核心库的类文件(如 java.lang.String)。这些食材非常基础,就像盐、油、糖这些每道菜都必须用的东西🧂。
  2. 扩展类加载器(Extension ClassLoader) 📦
    • 这个搬运工负责搬运扩展的食材🔧,也就是放在 ext 目录下的库文件。它会加载一些系统扩展库,就像是你准备了各种调料和香料🌶️,增加更多的功能。
  3. 应用程序类加载器(Application ClassLoader) 🍔
    • 这个搬运工专门负责加载我们自己写的代码📜,它会从你的项目路径下找到 Java 类文件。这就像是你把自己的菜谱交给搬运员,他帮你找到了特定的食材🥕🍗,然后带进厨房。

类加载的工作流程 📦➡️💻

  1. 首先,JVM 启动时,它会先用启动类加载器把最基本的 Java 类加载进来,比如 java.lang.Object(就像做饭你总得先有锅有火🔥)。
  2. 然后,扩展类加载器会加载一些附加功能,比如图形界面、网络功能等(相当于加点香料,让菜更有味道🌶️)。
  3. 最后,应用程序类加载器会加载你自己写的类文件,这就是你定义的业务逻辑部分。

双亲委派机制(Parents Delegation Model)👪🚚

现在重点来了!✨双亲委派机制可以看作是类加载器的工作方式。它确保每个类加载器都不会自己“偷偷摸摸”去加载类文件,而是先请它的“父母”加载。🧓👦

解释方式: 假设你在厨房做饭,你先让大厨手下最有经验的搬运工去找食材🍅,如果他找不到,才会轮到下一个搬运工。每个类加载器在加载类时,都会先请求它的“父母”类加载器看看是否已经加载过这个类。

双亲委派的步骤

  1. 如果你要加载一个类,应用程序类加载器不会直接去找,而是先问扩展类加载器:“你有没有这个类啊?”🤔
  2. 扩展类加载器也不会马上去找,而是继续问启动类加载器:“你有没有这个类?”🤔
  3. 启动类加载器会先尝试加载,如果找不到,权限才会返回给下一个类加载器,直到应用程序类加载器自己加载。

这个机制确保了 Java 核心类库不会被随便“篡改”。比如,如果你写了一个自己的 java.lang.String 类,双亲委派机制会让启动类加载器优先加载官方的 String 类,而不是你自定义的。👨‍🏫💡


双亲委派机制的现实类比 🍔👩‍👩‍👦

让我们用一个简单的生活类比来帮助你更好地理解这个机制:

想象你是一家餐厅的经理🍽️,有顾客点了一份汉堡🍔。你不会自己去厨房亲自做汉堡,而是会先问你最老练的大厨:“你知道怎么做这个汉堡吗?”🍳

  • 如果大厨知道怎么做,那一切搞定!🍔😋
  • 如果大厨不知道,他会去问负责配菜的小厨师👩‍🍳。
  • 最后,如果所有大厨都不懂,那你才会自己动手去做汉堡。

这个流程就是双亲委派机制,它确保程序中的类不会被误加载,先从最核心的地方找,找不到才会逐层往下找,直到最后一层。


总结 💡🎯

  • 类加载器:它是 JVM 中的搬运员,负责把类文件(Java 类)加载进来。
  • 双亲委派机制:它确保每个类加载器不会直接加载类,而是先让“父母”类加载器尝试加载,避免重复或篡改类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值