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

二、Java虚拟机的基本结构

Java虚拟机的架构

  • 1.内存结果概述
  • 2.类加载器子系统的作用
  • 3. 类加载器ClassLoader角色
  • 4.类的加载过程
  • 5.类加载器的分类
    • 1.引导类加载器(虚拟机自带的加载器)Bootstrap ClassLoader
    • 2.扩展类加载器(虚拟机自带的加载器) Extenssion ClassLoader
    • 3.应用程序类加载器(虚拟机自带的加载器)AppClassLoader
    • 4.用户自定义类加载器
    • 5.关于ClassLoader

1.内存结果概述

Java虚拟机那么复杂,它的基本结构是什么?各个组成部分有何作用?又是如何相互协调工作的呢?要解答这些问题就必须先了解Java堆、Java栈、永久区和元数据区的基本概念。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/e72bd95094bc4af1bb277a4ae5687474.jpeg

2.类加载器子系统的作用

1.类加载器子系统负责从文件或网络中加载Class文件,class文件在文件的开头有特定的文件标识。
2.ClassLoader只负责class文件的加载,至于类是否可运行,则有ExectionEngine决定。
3.加载的类的信息存放于一个称为方法区的内存空间,除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)

3. 类加载器ClassLoader角色

1.class file 存在于本地硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板在执行的时候是要加载到jvm当中来根据这个文件实例 化出n个一模一样的实例。
2.class文件加载到JVM中,被称为DNA元数据模板,放在方法区。
3.在类文件.class文件到->JVM->元数据模板,此过程就需要一个运输工具,类装载器Class Loader,扮演着一个快递元的身份。

在这里插入图片描述
在这里插入图片描述
恶意攻击有可能对字节码文件进行修改。

4.类的加载过程

在这里插入图片描述
加载:
1.通过一个类的全限定命名获取定义此类的二进制字节流
2. 将这个字节流代表的静态存储结构转化为方法区的运行时数据结构
3. 在内存中生成一个代表这给类的java.lang.Class对象,做为方法区这个类的各种数据访问入口。
加载.class的方式
1.从本地系统中获取。
2.从网络中获取。典型场景:Web Applet。
3.从zip压缩包中获取,称为日后jar,war格式的基础。
4.运行时计算生成,典型的场景:jsp应用
5.从专有数据库中提取.class文件
6.从加密文件中获取,典型的防Class文件被反编译的保护措施.

验证(Verify):
1.目的在于确保Class文件的字节流中包含的符号信息符合虚拟机的要求,保证被加载类的正确性,不会危害虚拟机的自身安全。
2.主要包含四种验证:文件格式的验证,元数据验证,字节码验证,符号引用验证。
准备(Prepare):
1.为类变量分配内存并设置默认初始值,即零值。
2.这里不包含final修饰的static,因为final在编译的时候就会分配了,准备阶段会显示初始化。
3.这里不会为实例变量分配初始化,类变量会分配在方法去中,而实例变量是会随着对象一起分配到java堆内存中。
解析(Resolve):
1.将常量池内的符号引用转换为直接引用的过程。
2.事实上,解析操作往往会伴随着Java虚拟机在执行完初始之后再执行。
3.符号引用就是一组符号用来描述所有引用的目标。符号引用的字面量形式明确定义在<java虚拟机规范>的class文件格式中,直接引用就是直接指向目标的指针,相对的偏移量或一个间接定位到目标的句柄。
4.解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的CONSTANT_CLASS_info、CONSTANT_Fieldref_info、CONSTANT_Methoftrf_info等。
初始化:
1.初始化阶段几十执行类构造器方法()的过程
2.此方法不需要定义,是javac编译器自收集类中所有类变量的赋值动作和静态代码块中的语句合并起来。
3.构造器方法中指令按语句在源文件中出现的顺序执行。
4.()不同于类的构造器
5.若该类具有父类,jvm会保证子类()执行前,父类的()已经执行完毕。
6.虚拟机必须保证一个类的()方法在多线程下被同步加锁。
在这里插入图片描述
若类中没有静态变量或静态代码块,类构造器方法()就不会生成。
任何一个类声明以后,内部至少存在一个类构造器()
在这里插入图片描述
IDEA安装jclasslib Bytecos Viewer插件可以查看编译后的字节码文件内容,插件安装后重启IDEA
在这里插入图片描述
查看编译后的字节码文件
在这里插入图片描述

在这里插入图片描述
下面代码的执行顺序为:ClassInintTest类加载完成—>调用静态方法main()–>调用Son—>加载并初始化Father—>加载并初始化Son—>结果等于2
在这里插入图片描述
先引入A值,再引入B值
在这里插入图片描述

5.类加载器的分类

1.JVM支持两种类型的类加载器,分别为引导类加载器(Bootstrap ClassLoader) 和自定义类加载器(User-Defind ClassLoader).(JAVA的核心类库都是引导类加载器加载的)
2.从概念上来讲,自定义类加载器以一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范并没有这么定义,而是将所有派生出来的抽象类ClassLoader的类加载器都划分为自定义类加载器。
3.无论类加载器的类型如何划分,在程序中我们最常见的类加载器始终只有3个:

1.引导类加载器(虚拟机自带的加载器)Bootstrap ClassLoader

1.这个类加载使用C/C++的语言实现的,嵌套在JVM内部。
2.它用来加载Java的核心类库,(JAVA_HOME/jre/lib/rt.jar resources.jar 或sun,boot.class.path路径下的内容),用于提供JVM自身需要的类.
3.并不继承自java.lang.ClassLoader,没有父加载器。
4.加载扩展类和应用程序类加载器,并指定为他们的父类加载器。
5.出于安全考虑,Bootstrap 启动类加载器只加载名为Java、javax、sun等开头的类。

获取BootstrapClassLoader能够加载的api路径
在这里插入图片描述

2.扩展类加载器(虚拟机自带的加载器) Extenssion ClassLoader

1.Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。
2.派生于ClassLoader类
3.父类加载器为启动类加载器。
4.从java.ext.dirs系统属性锁指定的目录中加载类库,或从JDK的安装目录的jre/lib.ext子目录(扩展目录)下载类库,如果用户创建的JAR放在此目录下,也会自动i用由扩展类加载器加载。
在这里插入图片描述

3.应用程序类加载器(虚拟机自带的加载器)AppClassLoader

1.java语言编写,由sun.misc.LauncherAppClassLoader实现。2.派生于ClassLoader类。3.父类加载器为扩展类加载器。4.它负责加载环境变量classpath或系统属性,java.class.path指定路径下的类库。5.该类加载器是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载。6.通过ClassLoaderAppClassLoader实现。 2.派生于ClassLoader类。 3.父类加载器为扩展类加载器。 4.它负责加载环境变量classpath或系统属性,java.class.path指定路径下的类库。 5.该类加载器是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载。 6.通过ClassLoaderAppClassLoader实现。2.派生于ClassLoader类。3.父类加载器为扩展类加载器。4.它负责加载环境变量classpath或系统属性,java.class.path指定路径下的类库。5.该类加载器是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载。6.通过ClassLoadergetSystemClassLoader()方法可以获取到该类加载器。

4.用户自定义类加载器

在java的日常应用程序开发中,类加载器几乎是由上述3中类加载器相互配合执行的,在必要=时,我们还可以自定义类加载器,来定制类的加载方式。

为什么要用自定义类加载器呢。
1.隔离加载类(例如系统jar包与中间jar不冲突,由于可能存在类冲突,未必免冲突)
2.修改类加载的方(除了引导类加载器BootstrapLoader加载所需的核心类之外有些类不是必须的,可以等到需要用的时候在引入)
3.扩展加载源(加载的类可以是本地的物理磁盘也可以是网络或者数据库等其他方式加载字节码文件来源)
4.防止源码泄露

用户自定义类加载器实现的步骤:
1.开发人员可以通过继承抽象类java.lang.ClassLoader类的方式,实现直自己的类加载器,以满足一些特殊的需求。
2.在JDK1.2之前,在自定义类加载器时,总会取继承ClassLoader类并重些写loadClass()方法,从而实现自定义类加载,但是在JDK1.2之后
已不再建议用户去覆盖loadClass()方法,而是建议把自定义的类加载逻辑写再findClass()方法中。
3.在编写自定义类加载器时,如过没有太过于复杂的需求,可以直接继承URLClassLoader类。这样就可以避免自己去编写findClass()方法及其获取字节码流的方式,使自定义类加载器编写更简洁。

import java.io.FileNotFoundException;public class CustomClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {byte[] result = getClassFromCustomPath(name);if (result == null) {throw new FileNotFoundException();} else {return defineClass(name, result, 0, result.length);}} catch (FileNotFoundException e) {e.printStackTrace();}throw new ClassNotFoundException(name);}private byte[] getClassFromCustomPath(String name){//从自定义路径中加载指定类:细节略//如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作。return null;}public static void main(String[] args) {CustomClassLoader customClassLoader = new CustomClassLoader();try {Class<?> clazz = Class.forName("One",true,customClassLoader);Object obj = clazz.newInstance();System.out.println(obj.getClass().getClassLoader());} catch (Exception e) {e.printStackTrace();}}
}

5.关于ClassLoader

ClassLoader类,它是一个抽象类,其后所有的类加载器都继承自ClassLoader(不包括启动类加载器)
getParent(); 返回该类加载器的超类加载器。
loadClass(String name) 加载名称为name的类,返回结果为java.lang.Class类的实例。
findClass(String name) 查找名称为name的类,返回结果为java.lang.Class类的实例。
findLoadedClass(String name) 查找名称为name的已经被加载过的类,返回结果为java.lang.Class类的实例。
defindClass(String name ,bytr[] b,int off,int len) 把字节数组b中的内容转换为一个Java类,返回结果为java.lang.Class类的实例,
resolveClass(Class<?> c) 链接一个指定的java类。

相关文章:

二、Java虚拟机的基本结构

Java虚拟机的架构1.内存结果概述2.类加载器子系统的作用3. 类加载器ClassLoader角色4.类的加载过程5.类加载器的分类1.引导类加载器(虚拟机自带的加载器)Bootstrap ClassLoader2.扩展类加载器(虚拟机自带的加载器) Extenssion ClassLoader3.应用程序类加载器(虚拟机自带的加载器…...

华为OD机试 - 用户调度(Python) | 机试题+算法思路+考点+代码解析 【2023】

用户调度 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度,会得到不同系统消耗的性能。 假设由N个待串行用户,每个用户可以使用A/B/C三种不同的调度策略。 不同的策略会消耗不同的系统资源,请你根据如下规则进行用户调度,并返回总的消耗资源数。 规则是: …...

HashMap(JDK1.8)源码+底层数据结构分析

HashMap 简介底层数据结构分析 JDK1.8 之前JDK1.8 之后 HashMap 源码分析 构造方法put 方法get 方法resize 方法 HashMap 常用方法测试 感谢 changfubai 对本文的改进做出的贡献&#xff01; HashMap 简介 HashMap 主要用来存放键值对&#xff0c;它基于哈希表的 Map 接口实现…...

case的使用

1.x和z值 1.1.定义 x&#xff1a;表示不定值 z&#xff1a;表示高阻态&#xff0c;还有一种表达方式“&#xff1f;” 一个x/z可以用来定义十六进制&#xff08;h&#xff09;数的4位二进制的状态&#xff0c;八进制&#xff08;o&#xff09;数的3位&#xff0c;二进制&#x…...

Mac配置ITerm2

Mac配置ITerm2 install-shell-integration配置lrzsz配置zsh安装Oh-My-Zsh修改皮肤文件加载皮肤添加插件配置profiles 1.expect配置文件2.shell脚本 iterm2顶部白条闪烁 install-shell-integration 安装完成之后会有一个指示标&#xff0c;需要弄掉Preferences > Profiles …...

JUC并发编程(下)

✨作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 学习地址 写在最前 JUC并发编程&#xff08;上&#xff09; JUC&#xff08;Java Util Concurrent&#xff09;学习内容框架&…...

API接口的基础知识

API是应用程序编程接口&#xff08;Application Programming Interface&#xff09;的缩写&#xff0c;能够起到两个软件组件之间的连接器或中介的作用。此类接口往往通过一组明确的协议&#xff0c;来表示各种原始的请求和响应。API文档可以向开发人员展示请求和响应是如何形成…...

基于Spring Boot的教务管理系统

文章目录项目介绍主要功能截图&#xff1a;登录首页学生信息管理班级信息管理教师信息管理教师评价部分代码展示设计总结项目获取方式&#x1f345; 作者主页&#xff1a;Java韩立 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题…...

网页扫描图像并以pdf格式上传到服务器端

本文描述如何通过网页驱动扫描仪、高拍仪等图像扫描设备进行图像扫描&#xff0c;扫描结果经编辑修改后以pdf压缩格式上传到后台java程序中进行服务器端落盘保存。图像扫描上传如文字描述顺序所介绍&#xff0c;先要驱动扫描设备工作&#xff0c;进行纸张数据的光学扫描操作形成…...

Airbyte入门

Airbyte 后端技术栈Java 17框架&#xff1a;JerseyAPI&#xff1a; OAS3数据库&#xff1a;PostgreSQL单元和E2E测试&#xff1a;JUnit 5编排&#xff1a;Temporal连接器技术栈连接器可以用任何语言编写。但是&#xff0c;最常见的语言是&#xff1a;Python3.9.0Java 17前端技术…...

研究人员在野外发现大量的信息窃取者 “Stealc “的样本

一个名为Stealc的新信息窃取者正在暗网上做广告&#xff0c;它可能成为其他同类恶意软件的一个值得竞争的对象。 "SEKOIA在周一的一份报告中说&#xff1a;"威胁行为者将Stealc作为一个功能齐全、随时可用的窃取者&#xff0c;其开发依赖于Vidar、Raccoon、Mars和Re…...

数据结构——复杂度讲解(2)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年2月22日 内容&#xff1a;数据结构复杂度讲解 目录 前言&#xff1a; 复杂度讲解&#xff08;2&#xff09;&#xff1a; 1.空间复杂度是什么&#xff1a; 2.空间复杂度讲解&#xff1a; 结尾&#xff1a; 前言&#x…...

【LeetCode】任务调度器 [M](贪心)

621. 任务调度器 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行&#xff0c;并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间&…...

Spring代理模式——静态代理和动态代理

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Anaconda和PyCharm的一些安装问题和命令

今天更新了Windows上的Anaconda到2.3.2&#xff0c;PyCharm到2022.3。 ——发现是纯纯的犯贱orz。出了一堆问题。在这里记录一下供后来者参考。 Anaconda安装 将.\anaconda3\Scripts 和.\anaconda3\Library\bin添加到系统环境变量中。 新建环境的目录在.\anaconda3\envs下 N…...

sql优化建议

对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。 应尽量避免在 where 子句中使用!或<>操作符&#xff0c;否则将引擎放弃使用索引而进行全表扫描。 应尽量避免在 where 子句中对字段进行 null 值判断&a…...

google hacker语句

哎&#xff0c;我就是沾边&#xff0c;就是不打实战(&#xffe3;o&#xffe3;) . z Z 文章目录前言一、什么是谷歌Docker&#xff1f;二、受欢迎的谷歌docker语句谷歌docker的例子日志文件易受攻击的 Web 服务器打开 FTP 服务器SSH私钥电子邮件列表实时摄像机MP3、电影和 PDF…...

Spring AOP

Spring AOP 文章目录Spring AOP1.概念1.面向切面编程2.AOP的目的3.AOP实现的分类4.AOP 术语2. Spring AOP的特性1.能力与目标2.AOP机制1.理解SpringAOP的代理2.AOP代理类的自调用代码的粒度如何让自调用走代理&#xff1f;3.Enabling AspectJ Support3. 定义切面与切点1. 声明切…...

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理

“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向&#xff0c;进行企业、品牌战略、品牌营销的制订和落地&#xff0c;企业经营的每个环节和输出的每个动…...

python居然能语音控制电脑壁纸切换,只需60行代码

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 家在日常的电脑使用中&#xff0c;都会有自己喜爱类型的桌面 单纯的桌面有时候会让人觉得单调 今天&#xff0c;就由我带领大家只用60行代码打造一款语音壁纸切换器程序&#xff0c; 让大家能够通过语音的方式来控制电脑去…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...

PLC入门【4】基本指令2(SET RST)

04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C)&#xff0c;从 文件 - 主画面&#xff0c;“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...

运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.

报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符&#xff0c;最后运行&#xff1a;npm run lint --fix...