JVM基础学习---1、JVM总体机制、类加载机制

news2024/11/27 0:37:39

1、JVM总体机制

1.1 JVM概念在这里插入图片描述

JVM:Java Virtual Machine,翻译过来是Java虚拟机。
JRE:Java Runtime Environment,翻译过来是Java运行时环境。

  • JDK:Java Development Ki

JDK:Java Development Kits,翻译过来是Java开发工具包

  • JDK=JRE+Java开发辅助工具

JVM工作的总体机制

1、Java源程序编译运行过程
Java源程序–>编译–>字节码文件–>放到JVM上运行
2、JVM工作的总体运行机制

  • 第一步:使用类加载子系统将*.class字节码文件加载到JVM内存
  • 第二步:在JVM的内存空间存储相关数据。
  • 第三步:在执行引擎中将*.class字节码文件翻译成CPU能够执行的指令。
  • 第四步:将指令发给CPU执行。

在这里插入图片描述

2、类加载机制

2.1 类加载器

1、概念

  • 类加载器子系统负责从文件系统或者网络中加载*.class字节码文件。
  • 字节码文件开头必须有特定的文件标识。如果使用二进制文件查看工具打开Java编译得到的字节码文件,会发现,文件开头是:CA FE BA BE。它们都是十六进制数的符号。
  • ClassLoader只负责字节码文件的加载,至于它是否可以运行,则由Execution Engine执行引擎决定的。
  • 加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字字面量(这部分常量信息是字节码文件中常量池部分的内存映射)。
    在这里插入图片描述
    2、分类
    在这里插入图片描述
    JVM中类加载器分为四种:前三种为虚拟机自带的加载器。
中文名称英文名称说明
启动类加载器BootstrapC++语言编写,不是ClassLoader子类·,Java中为null
扩展类加载器Extensionsun.misc.Launcher.ExtClassLoader
应用类加载器AppClassLoadersun.misc.Launcher.AppClassLoader
自定义类加载器程序员自己开发一个类继承java.lang.ClassLoader,定制类加载方式

3、父子关系

  • 父子关系1:启动类加载器是扩展类加载器的父加载器
  • 父子关系2:扩展类加载器是应用类加载器的父加载器

注意:这里说的父子关系不是通过继承实现的,不是类型上的父子关系。而是在子加载器中通过parent属性指向父加载器这样建立的—是对象之间逻辑上的父子关系。

4、通过代码查看类加载器

// 1.获取Person类的Class对象
// 2.通过Class对象进一步获取它的类加载器对象
ClassLoader appClassLoader = Person.class.getClassLoader();

// 3.获取appClassLoader的全类名
String appClassLoaderName = appClassLoader.getClass().getName();

// 4.打印appClassLoader的全类名
// sun.misc.Launcher$AppClassLoader
System.out.println("appClassLoaderName = " + appClassLoaderName);

// 5.通过appClassLoader获取扩展类加载器(父加载器)
ClassLoader extClassLoader = appClassLoader.getParent();

// 6.获取extClassLoader的全类名
String extClassLoaderName = extClassLoader.getClass().getName();

// 7.打印extClassLoader的全类名
// sun.misc.Launcher$ExtClassLoader
System.out.println("extClassLoaderName = " + extClassLoaderName);

// 8.通过extClassLoader获取启动类加载器(父加载器)
ClassLoader bootClassLoader = extClassLoader.getParent();

// 9.由于启动类加载器是C语言开发的,在Java代码中无法实例化对象,所以只能返回null值
System.out.println("bootClassLoader = " + bootClassLoader);

2.2 双亲委派机制

『双亲委派机制』这个名字不能顾名思义。在中文语境下,双亲是指父母;但是这里实际上是指『爸爸』和『爷爷』。所以我觉得应该叫:祖孙三代,比拼啃老机制,更贴切。
1、机制简介
在这里插入图片描述

  • 当我们需要加载任何一个范围内的类时,首先要找到这个范围对应的类加载器

  • 但是当前这个类加载器不是马上开始查找

  • 当前类加载器会将任务交给上一级类加载器

  • 上一级类加载器继续上交任务,一直到最顶级的启动类加载器

  • 启动类加载器开始在自己负责的范围内查找

  • 如果能找到,则直接开始加载

  • 如果找不到,则交给下一级的类加载器继续查找

  • 一直到应用程序类加载器

  • 如果应用程序类加载器同样找不到要加载的类,那么就会抛出ClassNotFoundException。
    2、实验
    (1)实验1

  • 第一步:在与JDK无关的目录下创建Hello.java

public class Hello {
  
  public static void main(String[] args){
    System.out.println("AAA");
  }
  
}
  • 第二步:编译Hello.java
  • 第三步:将Hello.class文件移动到$JAVA_HOME/jre/classes目录(没有就自己创建一个)下
  • 第四步:修改Hello.java
public class Hello {
  
  public static void main(String[] args){
    System.out.println("BBB");
  }
  
}
  • 第五步:编译Hello.java
  • 第六步:将Hello.class文件移动到$JAVA_HOME/jre/lib/ext/classes目录(没有就自己创建一个)下
  • 第七步:修改Hello.java
public class Hello {
  
  public static void main(String[] args){
    System.out.println("CCC");
  }
  
}
  • 第八步:编译Hello.java
  • 第九步:使用java命令运行Hello类,发现打印结果是:AAA
    • 说明Hello这个类是被启动类加载器找到的,找到以后就不查找其他位置了
  • 第十步:删除$JAVA_HOME/jre/classes目录
  • 第十一步:使用java命令运行Hello类,发现打印结果是:BBB
    • 说明Hello这个类是被扩展类加载器找到的,找到以后就不查找其他位置了
  • 第十二步:删除$JAVA_HOME/jre/lib/ext/classes目录
  • 第十三步:使用java命令运行Hello类,发现打印结果是:CCC
    • 说明Hello这个类是被应用程序类加载器找到的

(2)实验2

  • 第一步:创建假的String类
package java.lang;

public class String {

    public String() {
        System.out.println("嘿嘿,其实我是假的!");
    }

}
  • 第一步:编写测试程序类
    @Test
    public void testLoadString() {

        // 目标:测试不同范围内全类名相同的两个类JVM如何加装
        // 1.创建String对象
        java.lang.String testInstance = new java.lang.String();

        // 2.获取String对象的类加载器
        ClassLoader classLoader = testInstance.getClass().getClassLoader();
        System.out.println(classLoader);
    }
  • 第三步:查看运行结果是null
    • 假的String类并没有被创建对象,由于双亲委派机制,启动类加载器加载了真正的String类.

2.3 小结

双亲委派机制的好处:

  • 避免类的重复加载:父加载器加载了一个类,就不必让子加载器再去查找了。同时也保证了在整个JVM范围内全类名是类的唯一标识。
  • 安全机制:避免恶意替换JRE定义的核心API(沙箱安全机制)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/551493.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql字符集

1、修改MySQL5.7字符集 我们在新建数据库时(Navicat)界面时会遇到这两个选项,字符集和排序规则 在MySQL 8.0版本之前,MySQL 5.7 默认的客户端和服务器都用了 latin1 ,而latin1是不包含中文的,所以保存中文…

MetersPhere 试用

1. 功能测试 1.1 用例管理 脑图管理 样式: 脑图用例导入 1.2 用例评审 1.2.1 发起用例评审 1.2.2 关联用例: 1.2.3 用例评审 2. 接口测试 2.1 接口定义 类似postman、foxapi等主流接口管理页面 2.2 用例配置: 需要在meterphere安装节点…

路径规划算法:基于人工蜂群算法的路径规划算法- 附代码

路径规划算法:基于人工蜂群的路径规划算法- 附代码 文章目录 路径规划算法:基于人工蜂群的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要:本文主要介绍利用智能优化算法人工…

C++ [STL之vector的使用]

本文已收录至《C语言和高级数据结构》专栏! 作者:ARMCSKGT STL之vector的使用 前言正文默认成员函数普通构造拷贝构造析构函数赋值重载 迭代器正向迭代器反向迭代器const迭代器 容量类空间容量查询空间容量操作扩容操作元素数量操作缩容操作 数据访问下标…

numpy log随机产生非常奇怪的数字(np.log的大坑)

背景 有一批信号数据要送到网络里训练,训练之前为了统一量纲,首先根据方差和均值做了一次标准化,然后求了一次能量(20*log10(x)),也就是说送进网络里的其实是一个能量谱,但是训练过程中经常蹦出…

Python的用途与学习计划

python的用途: 1、web开发; 2、网络爬虫; 3、数据科学; 4、自动化运维; 5、数据库编程; 6、网络编程; 7、图形处理、数学处理、文本处理; 8、多媒体应用。 其中&#xff0c…

组合问题-回溯算法

1题目 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ] 示例 2: 输入:n …

美国国际留学生超136万,本科、硕士和博士各占多少?

国际教育市场研究机构ICEF Monitor近日公布,2022年美国持有F-1和M-1有效学习签证的国际学生数量共计136.2万人,与2021年相比增长了10.1%。 其中,国际学生来美国读本科学士学位的占37%,读硕士学位的占41%,读博士学位的…

为什么WordPress这么难用?(以及如何让它变得简单点)

WordPress 是世界上最受欢迎的网站构建器,为互联网上超过 43% 的网站提供支持。然而,有些人抱怨说 WordPress 比 Squarespace 和 Wix 等解决方案更难使用。 在本文中,我们将解决为何WordPress这么难用的神话,并分享您可以用来毫无…

用于具有缺失模态的脑肿瘤分割的模态自适应特征交互

文章目录 Modality-Adaptive Feature Interaction for Brain Tumor Segmentation with Missing Modalities摘要本文方法Modality-Adaptive Feature InteractionGraph RepresentationGraph Edge ComputationModality Feature Updating 实验结果 Modality-Adaptive Feature Inter…

OpenCV入门-基于Python

图像入门 1. 创建窗口namedWindow()resizeWindow()destroyAllWindow() 2.显示图像imread()imshow()imwrite()waitKey()flip() 代码演示3.显示视频VideoCapure()对象cap.get()cap.isOpened()cap.read()cap.release() 部分功能代码演示VideoWriter()对象VideoWriter_fourcc()writ…

K8s之Pod生命周期、启动停止钩子

文章目录 一、Pod生命周期流程二、初始化容器-initContainers三、主容器操作-containers1、启动钩子-lifecycle.postStart2、停止钩子-lifecycle.preStop 一、Pod生命周期流程 Pod生命周期整个过程 如下图: 1、在启动任何容器之前,前创建 pause 容器&am…

u-boot移植:详细讲解移植u-boot.2022.10版本到imx6ull开发板

目录 一、u-boot编译环境准备 1.安装交叉编译工具链 2.u-boot源码包下载 3.编译 4.安装依赖库 二、U-Boot中添加自己的开发板 1、添加开发板默认配置文件 2、添加开发板对应的头文件 3、添加开发板对应的板级文件夹 4、修改 arch/arm/mach-imx/mx6/Kconfig 5、其他需…

5分钟使用UNI-APP框架创建你的第一个项目

UNI-APP学习系列 5分钟使用UNI-APP框架创建你的第一个项目 文章目录 UNI-APP学习系列前言uni-app框架创建项目一、HBuilderX可视化方式二、 vue-cli命令行方式 总结 前言 UNI-APP学习系列之5分钟创建自己的第一个uni-app项目。 uni-app框架创建项目 创建方式 一、HBuilderX可…

bash: /opt/ros/kinetic/setup.bash: 没有那个文件或目录

有时候打开终端的时候,会在第一行报错: bash: /opt/ros/kinetic/setup.bash: 没有那个文件或目录 bash: /opt/ros/melodic/setup.bash: 没有那个文件或目录 bash: /opt/ros/neodic/setup.bash: 没有那个文件或目录 凡是类似报错与bash有关的&#xf…

【PCIE703】XCKU060+海思视频处理器HI3531DV200-ARM的高性能综合视频图像处理平台设计资料及调试经验

板卡概述 PCIE703是我司自主研制的一款基于PCIE总线架构的高性能综合视频图像处理平台,该平台采用Xilinx的高性能Kintex UltraScale系列FPGA加上华为海思的高性能视频处理器来实现。 华为海思的HI3531DV200是一款集成了ARM A53四核处理器性能强大的神经网络引擎&am…

架构-软件工程模块-2

系统分析 数据流图可能出案例题,状态转换图了解作用即可 用例图、类图选择题多,暴徒了解即可 #mermaid-svg-lGozbtkYJPEQF1eo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lGozbtkYJPEQF1e…

加密那些事

一、前言 说到加解密也许有些人会有些陌生(仅对于初学者或其他行业的学者),先不说那些让人看到千篇一律的概念,就是如果两个人发信息怎样才能不被第三个人知道呢?是不是脑海里冒出了使用某种暗号,只有相互传…

每一个“大佬级别”的测试工程师,都有着怎样的成长那个路线?3分钟为你揭晓谜底!

目录 引言 1.何为软件测试工程师? 2.软件测试工程师的职责? 3.为什么要做软件测试? 4.软件测试的前途如何? 5.工具和思维谁更重要? 6.测试和开发相差大吗? 7.成为测试工程师的必备条件 8.测试的分…

虚拟机栈概述

一、概述 1.1、虚拟机栈背景 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功…