JVM(2)

JVM类加载

指的是java进程运行时,需要把.class文件从硬盘加载到内存,并进行一系列校验解析的过程.

核心: .class文件=>类对象;   硬盘=>内存.

类加载过程

在整个JVM的执行流程中,和程序员关系最密切的就是类加载的过程了,所以我们来看一下类加载的执行流程.

对于一个类,它的生命周期是这样的:

其中前五步是固定的顺序也是类的加载过程,其中中间的三步我们都属于连接,所以类加载有以下几个步骤: 

1.加载

2.连接

        a.验证

        b.准备

        c.解析

3.初始化

下面我们来看每个步骤的具体内容.

加载

定义:把硬盘上的.class文件,找到,打开文件,读取到文件指定内容.

 "加载"截断是整个"类加载"的过程中的一个阶段,它和类加载ClassLoading是不同的,一个是加载Loading另一个是类加载ClassLoading,所以不要把两者搞混了.

在加载Loading阶段,Java虚拟机需要完成以下事情:

(1)通过一个类的全限定名来获取此类的二进制字节流.

(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.

(3)在内存中生成一个代表这个类的java.lang.class对象,作为方法区这类的各种数据访问入口.

验证

验证是进行连接阶段的第一步,这一阶段的目的是确保Class文件的字节流中包含的信息符合 Java虚拟机 规范的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全.

验证选项:

文件格式验证

字节码验证

符号引用验证 

 准备

定义:给类对象申请内存空间.里面默认值全0(这个阶段中,类对象静态成员变量也是相当于0了).

比如此时有这么一行代码:

pubilc static int value = 123;

它是初始化value的int值为0,而非123. 

解析

定义:针对类中的字符串进行处理,解析阶段是Java虚拟机常量池内的符号替换为直接引用的过程,也就是初始化常量的过程.

 例如如下程序:

class Test {

        private String s = "hello";

}
.class文件内会包含这个hello.

上述代码中,很明确的知道,s变量里相当于保存了"hello",也就是字符串常量的地址.但是在文件中,不存在"地址"这样的概念. 地址是"内存"的地址.咱们是文件,是硬盘.

虽然没有地址,但是可以先存储一个类似于地址"偏移量"这样的概念.

接下来,要把.class文件加载到内存中.就会先把"hello"这个字符串加载到内存中.此时"hello"就有地址了. 接下来,s里面的值就可以替换成当前"hello"真实的地址了.

直接引用=>此处文件中填充给s的"hello"的偏移量就可以认为是"符号引用".

初始化

定义:针对类对象后续的初始化,还要执行代码块的逻辑,还会触发父类加载,初始化静态成员,执行静态代码块.

初始化阶段,Java虚拟机真正开始执行类中编写的Java程序代码,将主导权交给应用程序.初始化阶段就是执行类构造器方法的过程.

双亲委派模型

提到类加载机制,不得不提的概念就是"双亲委派模型".(描述了如何找到.class文件的策略).

站在Java虚拟机角度来看,只存在两种不同的类加载器(进行类加载的专门模块):一种是启动类加载器(BootstrapClassLoader),这个类加载器使用C++语言实现,是虚拟机的一部分;另外一种就是其它所有的类加载器,这些类加载器都由Java实现,独立存在于虚拟机外部,全部继承于抽象类java.lang.ClassLoader. 作用:给一个"全限定类名"(带有包名的类名),给定之后,找到对应的.class文件.

这里面,加载器存在"父子关系"(不是面向对象中的),而是类似于"二叉树",有parent指针指向.

Bootstrap ClassLoader负责查找标准库中的目录.

ExtensionClassLoader负责查找扩展库中的目录.

Application ClassLoader负责查找当前项目的代码目录. 

启动类加载器:加载JDK中lib目录中的Java核心类库,即JAVA_HOME/lib目录.扩展类加载器.加载lib/ext目录下的类.

应用程序类加载器:加载我们写的应用程序.

自定义类加载器:根据自己的需求定制类加载器 

什么是双亲委派模型 

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类的加载器去完成,每一个层次的类都是如此,因此所有的加载请求最终都应该传送到最顶层的启动器的加载器当中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会自己尝试去完成加载.

具体流程:

1.从ApplicationClassLoader作为入口,先开始工作.

2.ApplicationClassLoader不会立即搜索自己负责的目录,要把搜索任务交给它的父亲

3.ExtensionClassLoader也不想立即搜索自己负责的目录,也把搜索目录交给自己的父亲.

4.BootstrapClassLoader也不想立即搜索,把搜索目录交给父亲.

5.BootstrapClassLoader发现自己没有父亲,才会真正搜索负责的目录(标准库目录).通过全限定类名,尝试在标准库目录中找符合要求的.class文件.

(1)如果找到了,接下来就直接进入到打开文件/读文件流程

(2)如果没找到,回到孩子这一辈的加载器中,尝试继续加载.

6.ExtensionClassLoader收到父亲交给他的任务后,自己自行搜索负责的目录.(当前项目目录/第三方目录)

(1)如果找到了,接下来进入后续的流程.

(2)如果没找到,也是回到孩子这一辈类加载器中继续加载.

7.ApplicationClassLoader收到父亲交给它的任务后,自己负责搜索的目录(当前项目目录/第三方目录)

(1)如果找到了,接下来就进入了后续流程

(2)如果未找到,也会回到这一辈的类加载器继续尝试加载.由于默认情况下ApplicationClassLoader没有孩子了,说明类加载的过程失败了,就出现ClassNotFoundException异常.

这样的过程,也与自己工作中问题处理逻辑一样:

当基层员工遇到一个问题时(自己拿不定主意),然后交给中层领导.,中层领导也拿不定,就会交给老板决定.老板如果能解决,就会直接解决,如果觉得没必要,就会交给中层领导,让它们自行解决,中层领导觉得自己能解决就会直接解决如果觉得没必要,就会交给员工解决.

这样的问题汇报是很重要的. 

按照上述的顺序,假定在代码中定义了一个java.lang.String这样的类,最终执行结果,自定义的类,不会被jvm加载.

上述的设定,也可以有效避免自己写的类,不小心和标准库中的类名重复,导致标准库的类名失效

上述一系列过程,也可以通过自己写一个类加载器打破原有过程,不过实现非常麻烦.

双亲委派模型的优点

1.避免重复加载类:比如A类和B类都有一个父类C类,那么A启动时就会将C类加载起来,那么在B类进行加载时就不需要重复加载C类了.

2.安全性:使用双亲委派模型也可以保证了Java核心的API不被篡改,如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个java.lang.Object类的话,那么程序运行的时候,系统就会出现多个不同的Object类,而有些Object类又是用户自己提供的因此安全性就不能得到保证了. 

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

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

相关文章

使用Git从其他分支merge个别文件

项目背景 产品经理:我们本次开发三个功能,列表页功能、详情页功能、系统消息功能,分两次上线,先上列表功能,再上详情页和系统消息。 小明:好的吧。 紧接着,小明就将本次需求分为2个分支&…

camunda7流程跳转和流程退回的实现方法

我们在使用工作流的时候,常常有“流程退回”、“流程跳转”、“自由流”、“动态加签”等这样的需求。Camunda流程平台提供了这样的机制和接口,虽然流程模型定义活动执行顺序的序列流,但有时需要灵活地重新启动活动或取消正在运行的活动&…

k8s-项目测试环境部署

部署规划 概述 项目开发好后,我们需要部署,我们接下来就基于 阿里云云效 阿里云容器镜像服务 k8s 搭建部署环境 阿里云云效 : 放代码,可以做cicd(https://www.aliyun.com/product/yunxiao) 阿里云容器镜像服务 :…

Unity(第十六部)声音和视频

声音 1、听声音 创建相机的时候,相机自带Audio Listener 多个相机的时候,我们只保留一个Audio Listener就可以 2、声音源,环境音 添加Audio Source就行中文叫声音源 3、脚本执行的声音 using System.Collections; using System.Collection…

Servlet(1)Request 请求对象

1、接收请求数据的流程 浏览器发送HTTP请求到Tomcat服务器HTTP的请求中会包含很多请求数据(请求行请求头请求体)Tomcat服务器会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中所封装的对象即为Request对象,所以可以从Request对象中…

ubuntu安装新版本的CMake

来到cmake官网选择版本 我需要在嵌入式板子上的Ubuntu18安装使用 故我选择aarch64版本。 按F12进入检查模式得到下载链接。 在板子上运行以下命令,获取安装脚本 wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-aarch64.s…

OpenCV实现目标追踪

目录 准备工作 语言: 软件包: 效果演示 代码解读 (1)导入OpenCV库 (2)使用 cv2.VideoCapture 打开指定路径的视频文件 (3)使用 vid.read() 读取视频的第一帧,ret…

前端视角对Rust的浅析

概述 本文将从 Rust 的历史,前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子,了解 Rust 如何应用到前端,提高前端的生产效率。 Rust简史 2006年,软件开发者Graydon Hoare在Mozilla工作期间&#…

队列的概念及使用

目录 一. 概念 二. 队列的使用 三. 队列模拟实现 四. 循环队列 五. 面试题 一. 概念 队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操…

IDEA基础——Maven配置tomcat

配置方案 一、配置maven-tomcat plugin插件(只最高支持到tomcat 8)~~1.添加镜像源,获取tomcat 8插件配置~~~~1.1 在pom.xml里先添加镜像源~~~~1.2 添加tomcat插件配置~~ 2. 添加tomact官方发布的插件配置(无需添加镜像源&#xff…

本届挑战赛季军方案:基于图网络及LLM AGENT的微服务系统异常检测和根因定位方法

aiboco团队荣获本届挑战赛季军。该团队来自亿阳信通。 方案介绍 本届挑战赛采用开放式赛题,基于建行云龙舟运维平台的稳定性工具和多维监控系统,模拟大型的生活服务APP的生产环境,提供端到端的全链路的日志、指标和调用链数据。参赛队伍在组…

vue中将某个不太规则的json转成对象,或者将对象转成json字符串

vue中将某个不太规则的json转成对象,或者将对象转成json字符串 以我自己做的项目某个不规则的json为例 将json对象转成json字符串: JSON.stringify(jsonData); 将不规则json字符串转成对象并获取对应的属性的值: JSON.parse(jsonData).Name…

云原生精品资料合集(附下载)

云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声,以应用价值为中心的云原生时代已经到,所以IT人员学习云原生正当时!最近跟各位大神征集了云原生的教程,行业报告和最佳实践,总有一款适…

蓝桥杯_中断系统

一 中断 中断,即cpu暂停执行当前程序,转而执行另外一段特殊程序,处理结束后。返回之前暂停程序继续执行。 中断向量,中断服务程序的入口地址,每个中断源都对应一个固定的入口地址。 中断服务函数,内核响应中…

【亚马逊云科技】通过Amazon CloudFront(CDN)快速访问资源

文章目录 前言一、应用场景二、【亚马逊云科技】CloudFront(CDN)的优势三、入门使用总结 前言 前面有篇文章我们介绍了亚马逊云科技的云存储服务。云存储服务主要用于托管资源,而本篇文章要介绍的CDN则是一种对托管资源的快速访问服务&#…

Socket网络编程(二)——UDP快速入门

目录 UDP相关概念UDP是什么为什么不可靠UDP能做什么UDP包最大长度 UDP单播、广播、多播概念1. 单播、广播、多播模型图2. ip地址分类3. 子网掩码的作用:4. 广播地址5. 网段划分6. 变长子网掩码 UDP核心APIAPI-DatagramSocketDatagramSocket构造方法DatagramSocket常…

6.5 共享数据

本节介绍Android的四大组件之一ContentProvider的基本概念和常见用法:首先说明如何使用内容提供器封装内部数据的外部访问接口,然后阐述如何使用内容解析器通过外部接口操作内部数据,最后叙述如何利用内容解析器读写联系人信息,以…

10_Vue

文章目录 Vue快速入门Vue的指令Vue的插值表达式V指令v-bind(单向绑定)v-model(双向绑定)v-on(事件监听)v-for(循环)v-text、v-htmlv-show(显示/隐藏)v-if&…

了解GPT:ChatGPT的终极指南

在人工智能(AI)的世界里,有一颗冉冉升起的新星正在革命性地改变我们与机器的交互方式:ChatGPT。在本文中,我们将深入研究什么是ChatGPT,为什么底层技术GPT如此强大,以及它是如何实现其卓越功能的…

excel导出标准化

虽然标题叫标准化,只不过是我自己的习惯,当一件事情变得流程标准化之后,开发程序就会飞快,开发评估工作总是 搞个1~2天,实则前端后端一起开发,1个小时就可以搞定。 1 前端 const exportXls async () >…