JVM—编译器、类加载的过程、双亲委派机制这些你还记得吗?

背景介绍

这两天在对JVM的知识进行回顾,顺便来分享分享,接下来也会有系列文章,欢迎大家一起讨论。

过程

为什么叫JVM?

Java Virtual Machine,java虚拟机。可以理解成一个以字节码为机器指令的CPU

有哪些特点呢?

  • 不同的运行平台,有不同的虚拟机
  • 屏蔽了底层运行平台的差别,实现了“一次编译,随处运行”

为什么JVM可以跨平台?

不同操作系统有不同的JVM,可以运行字节码文件。JVM只和class字节码文件有关系,任何语言只要能翻译成符合规范的class字节码文件,都能够被JVM运行

JDK、JRE、JVM三者关系

  • JDK:Java Development Kit(java开发者工具)
  • JRE:Java Runtime Environment(java运行时环境)
  • JVM:Java Virtual Machine(java虚拟机)

  • jdk包含了jre,还提供了程序所需要的工具(java和javac运行编译环境的,javadoc可以把java生成一篇文档,jar把程序打包成应用……),jdk提供了java开发的环境(需要这样一个平台你才能写java代码)。jdk包含了jre,在jre的基础上扩充了一些开发工具,让开发者可以使用
  • jre包含了jvm、函数库,jre运行时环境,只要安装了jre,就能运行java代码了
  • jvm虚拟机,可以当成一种规范,可以用软件实现,也可以用硬件实现,它相当于在所有的操作系统上模拟了一个小小的CPU去处理java相关的东西。实现了跨平台,jvm屏蔽了底层的一些差别,一次编译到处执行

JVM包含了哪些部分?

 注:这张图片引用自网上

接下来我针对JVM的每一部分起了哪些作用具体来说说吧!


一、编译器

为什么要用编译器?

我们在本地写的都是源代码,而电脑,也就是CPU只认识0和1,要想让电脑执行我们写的程序,就要翻译成电脑能够认识的语言0和1,这个翻译的过程就是编译器去做。


二、类加载子系统

类的加载过程(类的生命周期)

被javac编译之后的字节码文件是存在磁盘中的,而类加载的过程就是把字节码从磁盘加载到内存中的过程

 

1、加载(Loading):

作用:生成Class。类加载器通过类的全限定名在内存中成java.lang.Class类模板对象,作为方法区这个类的各种数据的访问入口

工作内容:

  • 将class信息,静态变量、常量加载到方法区
  • 将Class对象指向class信息

2、验证(Verify):

作用:确保Class文件是否符合当前虚拟机要求,保证被加载类的正确性,只有符合JVM字节码规范的才能被JVM正确执行

工作内容:

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

3、准备(Prepare):

作用:为成员变量分配内存并且设置该类变量的默认初始值,即零值

工作内容:

  • final不分配,在编译的时候就为final分配内存了,准备阶段会显式初始化
  • 不为实例变量分配初始化,类变量会分配在方法去中,实例变量会随着对象一起分配到Java堆中

4、解析(Resolve):

作用:将常量池内的符号引用转换为直接引用的过程

工作内容:

  • 类或接口、字段、类方法、接口方法、方法类型等

为什么要把符号引用转为直接引用?

在编译阶段java类并不知道所引用的实际地址,因此只能使用符号代替。比方说类A引用了类B,此时类A是不知道类B有没有被编译的,也不清楚类B的实际地址,所以用字符串S代表类B的地址,这个S就称为符号引用

  • 符号引用:可以理解为是一种占位符
  • 直接引用:可以理解为指向类、字段、方法存储在内存中的实际地址的指针

5、初始化:正常赋值,执行类构造器的过程
6、使用:执行main方法
7、卸载:销毁


类加载器

什么是类加载器?

负责加载类文件并生成对应的类对象的组件

类加载器的作用是什么?

类加载的时候是通过具体的类加载器去进行加载的,主要用于加载Class字节码文件

类加载器有哪几种分类?

  1. 引导类加载器(Bootstrap Class Loader):也称为根类加载器,是JVM的一部分,负责加载Java的核心类库,如rt.jar等。它是用本地代码实现的,不继承自java.lang.ClassLoader,因此无法直接获取到引导类加载器的引用。
  2. 扩展类加载器(Extension Class Loader):是由sun.misc.Launcher$ExtClassLoader实现的,负责加载Java的扩展类库,如jre/lib/ext目录下的jar包。它是Java类,继承自java.lang.ClassLoader。
  3. 应用程序类加载器(Application Class Loader):也称为系统类加载器,是由sun.misc.Launcher$AppClassLoader实现的,负责加载应用程序classpath下的类。它也是Java类,继承自java.lang.ClassLoader。
  4. 自定义类加载器(User Class Loader):用户通过继承java.lang.ClassLoader类的方法自行实现的类加载器

每个类加载器的区别是什么?

  • 加载的类目录不一样
  • 类的加载顺序不同
  • 可见性:类加载器可以根据需要通过父类加载器来委派加载类,但是父类加载器无法看到子类加载器加载的类

通过看底层的源码发现扩展类加载器和应用程序类加载器都是继承自ClassLoader类。而一个类只要继承了Classloader类,就是自定义类加载器

三个类加载器之间是什么关系?

层次关系,也称为双亲委派模型。每个类加载器之间互相配合、互相工作(类加载器都应该有自己的父类加载器,他们是组合关系去复用父类的代码)

什么是双亲委派模型(机制)?

当要加载一个类的时候会向上(父类)询问(委托)是否已加载过这个类,如果父类加载器无法加载该类,那么类加载器才会尝试自己加载

什么要使用双亲委派机制(好处)?
  • ①、避免类重复加载:提高类加载效率,保证数据安全

设想一个场景:用户在ClassPath中编写了一个java.lang.Object的同名类,如果没有双亲委派机制,每个类加载器都可以自行加载类,那么是不是会产生多个Object类呢?那程序使用的时候如何选择?唯一性就保证不了了

补充:全限定类名相同,并且类加载器是同一个,则会认为两个对象是同一个

  • ②、沙箱安全机制:保证核心.class不能被篡改

及时篡改也不会去加载,就算加载也不是同一个.class对象

总结

  • 在idea写的源码通过javac编译成机器认识的字节码文件
  • 字节码文件存储在磁盘中,想要到使用要通过类加载器把字节码文件加载到内存中
  • 类加载的需要通过双亲委派机制加载

升华

对于JVM的了解通过系统的回顾又有了新的发现,每次的反复都建立在原有的基础上不断精进,螺旋式上升引起量变到质变的过程

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flutter】【packages】simple_animations 简单的实现动画

package:simple_animations 导入包到项目中去 可以实现简单的动画, 快速实现,不需要自己过多的设置 有多种样式可以实现[ ] 功能: 简单的用例:具体需要详细可以去 pub 链接地址 1. PlayAnimationBuilder PlayAnima…

递归神经网络简介

一、说明 说起递归神经网络,递归神经网络(RNN)主要包括以下几种类型: 简单的RNN(Simple RNN):最基本的RNN类型,每个时刻的输出都与前面时刻的状态有关。 循环神经网络(R…

Blazor前后端框架Known-V1.2.10

V1.2.10 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行。 Gitee: https://gitee.com/known/KnownGithub:https://github.com/known/Known 概述 基于C#和Blazo…

Kafka:springboot集成kafka收发消息

kafka环境搭建参考Kafka&#xff1a;安装和配置_moreCalm的博客-CSDN博客 1、springboot中引入kafka依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><…

Python-OpenCV中的图像处理-形态学转换

Python-OpenCV中的图像处理-形态学转换 形态学转换腐蚀膨胀开运算闭运算形态学梯度礼帽黑帽形态学操作之间的关系 形态学代码例程 形态学转换 形态学操作:腐蚀&#xff0c;膨胀&#xff0c;开运算&#xff0c;闭运算&#xff0c;形态学梯度&#xff0c;礼帽&#xff0c;黑帽等…

B树的插入与删除过程

B树的插入 原树&#xff1a; 插入key后&#xff0c;若导致原节点关键字数超过上限&#xff0c;则从中间位置&#xff08; ⌈ m 2 ⌉ \lceil\frac{m}{2}\rceil ⌈2m​⌉&#xff09;将关键字分成两部分&#xff0c;左部分包含的关键字放在原节点中&#xff0c;右部分包含的关键…

前端下载文化部几种方法(excel,zip,html,markdown、图片等等)和导出 zip 压缩包

文章目录 1、location.href2、location.href3、a标签4、请求后端的方式5、文件下载的方式6、Blob和Base647、下载附件方法(excel,zip,html,markdown)8、封装下载函数9、导出 zip 压缩包相关方法(流方式) 总结 1、location.href //get请求 window.location.href url;2、locati…

死锁的成因,和解决方案总结

何为死锁 死锁是多线程或并发程序中的一种情况&#xff0c;当多个线程因为竞争资源而相互等待&#xff0c;并且无法继续执行的情况。在死锁中&#xff0c;每个线程都在等待其他线程释放资源&#xff0c;从而导致所有线程都陷入无限等待状态&#xff0c;无法继续向前执行&#…

0805hw

1. #include <myhead.h> void Bub_sort(int *arr,int n)//冒泡排序 {for(int i1;i<n;i){int count0;for(int j0;j<n-i;j){if(arr[j]>arr[j1]){int temparr[j];arr[j]arr[j1];arr[j1]temp;count;}}if(count0){break;}}printf("冒泡排序后输出结果:\n"…

uni-app离线打包高德地图导入android studio不能正常显示

本人使用的uni-app SDK版本&#xff1a;Android-SDK3.8.7.81902_20230704 1.导入以上文件&#xff0c;依赖已经自动添加了 2.确保这个正常引入 3.修改AndroidMainifest.xml,添加自己的密钥

整理mongodb文档:删

个人博客 整理mongodb文档:删 求关注&#xff0c;哪儿不足&#xff0c;求大佬们指出&#xff0c;哪儿写的不够通俗易懂跟清晰&#xff0c;也求指出 文章概叙 本文主要是介绍了删除数据的几个方法&#xff0c;主要还是在介绍deleteMany、deleteOne以及remove&#xff0c;对于…

JAVA基础之放弃使用Random

随机是日常生活中经常遇到的非常有趣的东西&#xff0c;比如说抛硬币&#xff0c;他的不可预知性总是让我们特别着迷&#xff0c;在拿不定主意时&#xff0c;有些人就喜欢用抛硬币的方式来帮助我们做决定。体育领域也喜欢用喜欢用抛硬币的方式来猜先。随机数功能是Java非常非常…

14个前端开发者应该知道的实用网站

在本文中&#xff0c;我将分享一些非常有用的网站合集&#xff0c;这些网站可以在你的日常工作中极大地帮助你。这些网站已经成为我各种任务的首选资源&#xff0c;节省了我的时间&#xff0c;提高了工作效率 文档自动化 Documatic 是一款专为开发人员设计的非常高效的搜索引擎…

Pytorch深度学习-----现有网络模型的使用及修改(VGG16模型)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

STM32 CubeMX USB_MSC(存储设备U盘)

STM32 CubeMX STM32 CubeMX USB_MSC(存储设备U盘&#xff09; STM32 CubeMX前言 《使用内部Flash》——U盘一、STM32 CubeMX 设置USB时钟设置USB使能UBS功能选择FATFS功能 二、代码部分修改代码"usbd_storage_if.c"修改代码"user_diskio.c"main函数初始化插…

每天一道leetcode:剑指 Offer 27. 二叉树的镜像(适合初学者递归树)

今日份题目&#xff1a; 请完成一个函数&#xff0c;输入一个二叉树&#xff0c;该函数输出它的镜像。 例如输入&#xff1a; 4 / \ 2 7 / \ / \ 1 3 6 9 镜像输出&#xff1a; 4 / \ 7 2 / \ / \ 9 6 3 1 示例 输入&#xff1a;root [4,2,7…

c基础扫雷

和三子棋一样&#xff0c;主函数先设计游戏菜单界面&#xff0c;这里就不做展示了。 初始化棋盘 初级扫雷大小为9*9的棋盘&#xff0c;但排雷是周围一圈进行排雷(8格)&#xff0c;而边界可能会越界。数组扩大了一圈,行和列都加了2&#xff0c;所以我们用一个11*11的数组来初始化…

数据结构—树和二叉树

5.树和二叉树 5.1树和二叉树的定义 树形结构&#xff08;非线性结构&#xff09;&#xff1a;结点之间有分支&#xff0c;具有层次关系。 5.1.1树的定义 树&#xff08;Tree&#xff09;是n&#xff08;n≥0&#xff09;个结点的有限集。 若n0&#xff0c;称为空树&#x…

Vue2嵌入HTML页面空白、互相传参、延迟加载等问题解决方案

一、需求分析 最近做的一个用H5加原生开发的html项目&#xff0c;现需要集成到Vue2.0项目里面来。遇到的相关问题做个记录和总结&#xff0c;以便能帮到大家避免踩坑。 二、问题记录 1、页面空白问题 将html页面通过iframe的方式嵌入进来之后&#xff0c;发现页面是空白的&am…

面试热题(倒数第k个结点)

输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表的尾节点是倒数第1个节点。 例如&#xff0c;一个链表有 6 个节点&#xff0c;从头节点开始&#xff0c;它们的值依次是 1、2、3、4、5、6。这个链表…