二、Java虚拟机的基本结构
Java虚拟机的架构
- 1.内存结果概述
- 2.类加载器子系统的作用
- 3. 类加载器ClassLoader角色
- 4.类的加载过程
- 5.类加载器的分类
- 1.引导类加载器(虚拟机自带的加载器)Bootstrap ClassLoader
- 2.扩展类加载器(虚拟机自带的加载器) Extenssion ClassLoader
- 3.应用程序类加载器(虚拟机自带的加载器)AppClassLoader
- 4.用户自定义类加载器
- 5.关于ClassLoader
1.内存结果概述
Java虚拟机那么复杂,它的基本结构是什么?各个组成部分有何作用?又是如何相互协调工作的呢?要解答这些问题就必须先了解Java堆、Java栈、永久区和元数据区的基本概念。

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 对本文的改进做出的贡献! HashMap 简介 HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现…...

case的使用
1.x和z值 1.1.定义 x:表示不定值 z:表示高阻态,还有一种表达方式“?” 一个x/z可以用来定义十六进制(h)数的4位二进制的状态,八进制(o)数的3位,二进制&#x…...

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

JUC并发编程(下)
✨作者:猫十二懿 ❤️🔥账号:CSDN 、掘金 、个人博客 、Github 🎉公众号:猫十二懿 学习地址 写在最前 JUC并发编程(上) JUC(Java Util Concurrent)学习内容框架&…...

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

基于Spring Boot的教务管理系统
文章目录项目介绍主要功能截图:登录首页学生信息管理班级信息管理教师信息管理教师评价部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题…...

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

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

研究人员在野外发现大量的信息窃取者 “Stealc “的样本
一个名为Stealc的新信息窃取者正在暗网上做广告,它可能成为其他同类恶意软件的一个值得竞争的对象。 "SEKOIA在周一的一份报告中说:"威胁行为者将Stealc作为一个功能齐全、随时可用的窃取者,其开发依赖于Vidar、Raccoon、Mars和Re…...

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

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

Spring代理模式——静态代理和动态代理
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

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

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

google hacker语句
哎,我就是沾边,就是不打实战( ̄o ̄) . z Z 文章目录前言一、什么是谷歌Docker?二、受欢迎的谷歌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代理类的自调用代码的粒度如何让自调用走代理?3.Enabling AspectJ Support3. 定义切面与切点1. 声明切…...

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理
“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向,进行企业、品牌战略、品牌营销的制订和落地,企业经营的每个环节和输出的每个动…...

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

内存泄露定位手段(c语言hook malloc相关方式)
如何确定有内存泄露问题,如何定位到内存泄露位置,如何写一个内存泄漏检测工具? 1:概述 内存泄露本质:其实就是申请调用malloc/new,但是释放调用free/delete有遗漏,或者重复释放的问题。 内存…...

STM32 CAN波特率计算
STM32 CAN波特率计算简介CAN总线收发,中断方式接收配置代码部分reference简介 CAN通信帧共分为数据帧、远程帧、错误帧、过载帧和帧间隔,本文这里以数据帧为例。 显性电平对应逻辑0,CAN_H和CAN_L之差为2.5V左右。而隐性电平对应逻辑1&#x…...

C/C++ 中#define 的妙用,让代码更美一些
C/C 中#define 的妙用,让代码更美一些 flyfish 1 数值类型输出易读的字符串形式 例如使用enum定义一些错误值,想要将数值类型的错误,输出易读的字符串形式 重要的一句代码 #define MAKE_PAIR(val) std::make_pair(val, #val)可以看到 #va…...

Linux文件系统操作与磁盘管理
查看磁盘和目录的容量 使用 df 命令查看磁盘的容量 df在实验楼的环境中你将看到如下的输出内容: 但在实际的物理主机上会更像这样: 物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示…...

【Python】批量采集原神表情包~
嗨害大家好鸭~我是小熊猫(✿◡‿◡) 最近迷上了原神, 不自觉中就很喜欢保存广大旅行者制作的表情包~ 真的很有意思诶~ 源码资料电子书:点击此处跳转文末名片获取 一个个保存的话,好像效率很低嘛… 那我就发挥我小熊猫的老本行直接给把他们全部采集下…...

C语言基本语法注释类型关键字
C 基本语法 标识符 给变量所取的名字叫变量名,定义变量的名字需要遵循标识符的命名规则。 标识符是用来标识变量、符号常量、数组、函数、文件等名字的有效字符序列。 标识符的命名规则: 1.只能由字母、数字和下划线组成(例如:…...

【C ++】C++入门知识(二)
C入门(二) 作者:小卢 专栏:《C》 喜欢的话:世间因为少年的挺身而出,而更加瑰丽。 ——《人民日报》 1.引用 1.1.引用的概念及应用 引用(&) 引用不是新定义一个变量࿰…...

qt qchart学习
Qt Charts主要由QChartView、QChart、QLegend图例、坐标轴(由QAbstractAxis子类实现)、**数据源(由QAbstractSeries子类实现)**等组成使用QChart的前期准备1. Qt5.9及以上版本;2. .pro文件中添加QT charts3. 在使用QChart的各个控件之前,引用头文件并必…...

手工布署 java 项目
新建一个java springboot项目 maven 这是一个非常简易的 springBoot 的项目 使用 maven 的 package 工具进行打包 把包上传到 linux 的机器上, 确保 linux 机器上安装了 java jdk工具, 并且配置好了 JAVA_HOME 注意,helloworld 默认的是要使…...

《设计模式》观察者模式
《设计模式》观察者模式 观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象可以同时监听和相应被观察者对象的状态变化,以达到解耦和复用的目的。观察者模式的优点如下: 解耦:观察者模…...