当前位置: 首页 > ops >正文

JVM详解

JVM就是Java虚拟机,Java虚拟机就是JVM

运行时数据区

类加载器

Java的类加载器遵循双亲委派模型,主要分为三个层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。启动类加载器是最顶层的,由C++实现,负责加载Java核心库如rt.jar。扩展类加载器负责加载扩展目录下的类,而应用程序类加载器则负责加载classpath下的类。用户自定义的类加载器通常继承自应用程序类加载器

  • 启动类(根)加载器(Bootstrap ClassLoader)
  • 扩展类加载器(Extension ClassLoader)
  • 应用程序(系统类)加载器(Application ClassLoader)
  • 虚拟机自带的加载器

public class Student {public static void main(String[] args) {Student student1 = new Student();Student student2 = new Student();Student student3 = new Student();System.out.println(student1.hashCode());System.out.println(student2.hashCode());System.out.println(student3.hashCode());System.out.println(student1.getClass());System.out.println(student2.getClass());System.out.println(student3.getClass());}
}

类是模板,对象是具体的

三个实例的 hashCode() 值通常不同,因为它们是独立的对象,内存地址不同。

Student 类被同一个类加载器加载,三个实例的 getClass() 返回的 Class 对象是同一个。如果通过不同的类加载器加载 Student 类(例如自定义类加载器),即使类名相同,JVM 也会认为它们是不同的类,导致 getClass() 返回不同的 Class 对象。

public class Student {public static void main(String[] args) {Student student1 = new Student();Student student2 = new Student();Student student3 = new Student();System.out.println(student1.hashCode());System.out.println(student2.hashCode());System.out.println(student3.hashCode());System.out.println(student1.getClass());System.out.println(student2.getClass());System.out.println(student3.getClass());Class<? extends Student> class1 = student1.getClass();ClassLoader classLoader = class1.getClassLoader();System.out.println(classLoader);//Application ClassLoaderSystem.out.println(classLoader.getParent());//Extension ClassLoaderSystem.out.println(classLoader.getParent().getParent());//null,1.找不到2.java程序获取不到}
}

我们可以看到 

  • Student 类由应用程序类加载器(Application ClassLoader)加载
  • 应用程序类加载器的父加载器是扩展类加载器(Extension ClassLoader)
  • 扩展类加载器的父加载器是启动类加载器(Bootstrap ClassLoader),但由于它是 JVM 内部用 C++ 实现的,Java 中无法直接获取其引用,因此返回 null

而在 Java 9 及更高版本中,由于模块化系统(JPMS)的引入,类加载器的结构和职责被重新设计:

  • Bootstrap ClassLoader:仍为顶层加载器,但不再直接暴露给开发者。
  • PlatformClassLoader平台类加载器):取代了 ExtClassLoader,负责加载平台模块(如 java.basejava.xml 等核心模块)。
  • AppClassLoader(应用程序类加载器):加载用户自定义的模块和 classpath 下的类。

双亲委托机制

主要目的:解决类加载冲突,即安全。

双亲委托流程
  1. 用户代码请求加载类:例如,AppClassLoader收到加载com.example.MyClass的请求。

  2. 向上委派

    • AppClassLoader先委派给父加载器PlatformClassLoader

    • PlatformClassLoader进一步委派给Bootstrap ClassLoader

  3. 逐级尝试加载

    • Bootstrap ClassLoader尝试加载核心类(如java.lang.String),若找到则返回。

    • 若未找到,PlatformClassLoader尝试加载平台模块中的类。

    • 若仍失败,AppClassLoader最终在用户模块或classpath下加载类。

Native 

Native 方法是 Java 中通过 JNI(Java Native Interface) 调用本地代码(如 C/C++ 编写的函数)的桥梁。即java的作用范围达不到,才调用底层C语言的库

JNI:扩展java的使用,融合不同的编程语言为java所用,在内存区域中开辟了一块标记区域(本地方法栈)登记native方法

程序计数器

程序计数器(PC寄存器)是 JVM运行时数据区 中一块线程私有的小内存空间,用于存储当前线程正在执行的字节码指令地址(或Native方法的执行状态)。

方法区

方法区是 JVM运行时数据区 的一部分,用于存储已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

  • 存储类的元数据(如类名、字段描述、方法字节码)。
  • 维护运行时常量池(包含字面量、符号引用)。
  • 存放静态变量static修饰的变量)和JIT编译后的本地代码

http://www.xdnf.cn/news/4854.html

相关文章:

  • 路由组件1
  • 创建没有 TPM 和安全启动的 Windows 11 可启动 USB 驱动器
  • 【MySQL】数据库、数据表的基本操作
  • SIGIR 2025端到端生成式推荐ETEGRec
  • 详解:ai证书有哪些?
  • MCP开发入门
  • C++ stl中的stack和queue的相关函数用法
  • uniapp 百家云直播插件打包失败
  • 在ISOLAR A/B 工具使用UDS 0x14服务清除单个DTC故障的配置
  • 基于大模型的母婴ABO血型不合溶血病全方位预测与诊疗方案研究
  • Java EE初阶——初识多线程
  • 纯净IP,跨境账号稳定的底层逻辑
  • Linux 文件系统中的数据定位:inode 与 dentry 的技术解析
  • CentOS 7 系统下安装 OpenSSL 1.0.2k 依赖问题的处理
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.1)
  • [Windows] 东芝存储诊断工具1.30.8920(20170601)
  • 【应急响应】- 日志流量如何分析?
  • 文本框碰撞测试
  • 基 LabVIEW 的多轴电机控制系统
  • element-ui时间线样式修改
  • vison transformer vit 论文阅读
  • 微软系统 红帽系统 网络故障排查:ping、traceroute、netstat
  • PDF文档解析新突破:图表识别、公式还原、手写字体处理,让AI真正读懂复杂文档!
  • 使用Python和OpenCV实现实时人脸检测与识别
  • C++ 观察者模式详解
  • 使用程序绘制中文字体——中文字体的参数化设计方案初探
  • 打造专属AI好友:小智AI聊天机器人详解
  • 【新品发布】VXI可重构信号处理系统模块系列
  • 麦科信获评CIAS2025金翎奖【半导体制造与封测领域优质供应商】
  • CI/CD面试题及答案