二、Java虚拟机的基本结构

news2024/11/30 12:52:49

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.Launcher A p p C l a s s L o a d e r 实现。 2. 派生于 C l a s s L o a d e r 类。 3. 父类加载器为扩展类加载器。 4. 它负责加载环境变量 c l a s s p a t h 或系统属性, j a v a . c l a s s . p a t h 指定路径下的类库。 5. 该类加载器是程序中默认的类加载器,一般来说, J a v a 应用的类都是由它来完成加载。 6. 通过 C l a s s L o a d e r AppClassLoader实现。 2.派生于ClassLoader类。 3.父类加载器为扩展类加载器。 4.它负责加载环境变量classpath或系统属性,java.class.path指定路径下的类库。 5.该类加载器是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载。 6.通过ClassLoader AppClassLoader实现。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 {

	@Override
	protected 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类。

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

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

相关文章

CAN TP层函数介绍

如果想使用CAN TP层函数,首先需要在网络节点或测试节点配置页面的Componets组件一栏添加osek_tp.dll文件。路径为:C:\Program Files\Vector CANoe 15\Exec32 至于节点的CAPL程序内需不需要引用这个dll文件,无所谓,可写可不写。但是如果是其他dll,必须在CAPL程序中引用。为…

多服务器节点访问解决一人一单问题+redis设置锁方案

项目地址及项目具体介绍-码云仓库&#xff1a;https://gitee.com/flowers-bloom-is-the-sea/distributeNodeSolvePessimisticLockByRedis 测试1&#xff1a; 这里使用jmeter同时启动2各线程&#xff1a; 原来的数据库表的数据&#xff1a; goods的数据是&#xff1a; id …

金蝶云星空物料批量禁用反禁用程序

【需求描述】&#xff1a;需要通过批量禁用反禁用操作物料。 【操作方法】&#xff1a; 下载附件批量禁用程序。 首先双击安装&#xff0c;一直下一步。 双击打开 会提示需要配置账套信息 点击菜单栏配置 输入相关配置信息 填写完毕后 然后点击下载模板导入要下载的数据 选…

Linux进程学习【三】

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f38a;每篇一句&#xff1a; 图片来源 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 Perseverance is not a long race; it is many short races one after another…

Word控件Spire.Doc 【Table】教程(18):如何在 C# 中的 Word 中创建嵌套表格

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

「JVM 编译优化」即时编译器

前端编译器&#xff08;javac&#xff09;将 Java 代码转为字节码&#xff08;抽象语法树&#xff09;&#xff0c;优化手段主要用于提升程序的编码效率&#xff1b; 后端编译器&#xff08;内置于 JVM 的 JIT/AOT Compiler&#xff0c;C1&#xff0c;C2&#xff09;将字节码转…

2022年休闲游戏市场总结

在预测 2023 年之前&#xff0c;我们先回顾一下 2022 年。从上一年发生的事件中往往能看到未来趋势的影子&#xff0c;所以 2022 年的总结至关重要。一、2022年总结回顾1、流行游戏类型回顾 2022 年&#xff0c;三种超休闲游戏表现最为突出&#xff1a;跑酷游戏&#xff1a;跑酷…

spring之声明式事务开发

文章目录一、声明式事务之全注解式开发1、新建springConfig类2、测试程序3、测试结果二、声明式事务之XML实现方式1、配置步骤2、测试程序3、运行结果附一、声明式事务之全注解式开发 基于之前的银行转账系统&#xff0c;将spring.xml配置文件嘎掉&#xff0c;变成全注解式开发…

【极海APM32替代笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

【极海APM32替代笔记】低功耗模式下的RTC唤醒&#xff08;非闹钟唤醒&#xff0c;而是采用RTC_WAKEUPTIMER&#xff09; 【STM32笔记】低功耗模式配置及避坑汇总 前文&#xff1a; blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置…

Spring Boot整合RabbitMQ教程

1.首页我们了解一下消息中间件的应用场景异步处理场景说明&#xff1a;用户注册后&#xff0c;需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 (1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。…

js实现轮播图

实现的效果图 原理:一次性加载所有图片&#xff0c;使用定位将图片重合在一起&#xff0c;根据opacity&#xff0c;z-index 属性显示当前图片 一、基本的HTML布局 创建一个外部容器来存放图片&#xff0c;prev-next是添加的左右切换按钮&#xff0c;dot存放图片下方的小白点…

《爆肝整理》保姆级系列教程python接口自动化(二十一)--unittest简介(详解)

简介 前边的随笔主要介绍的requests模块的有关知识个内容&#xff0c;接下来看一下python的单元测试框架unittest。熟悉 或者了解java 的小伙伴应该都清楚常见的单元测试框架 Junit 和 TestNG&#xff0c;这个招聘的需求上也是经常见到的。python 里面也有单元 测试框架-unitt…

小熊电器:精品与创意,走上“顶流之路”的两把“宝剑”

回顾2022年&#xff0c;小家电市场降温趋势明显&#xff0c;业绩表现整体低迷&#xff0c;如主打高端路线的北鼎&#xff0c;去年8亿元的营收出现个位数下滑&#xff0c;归母净利润同比下降超56%&#xff1b;苏泊尔营收也出现微降&#xff0c;归母净利润预计同比增长不到10%。而…

教你如何搭建培训机构-招生管理系统,demo可分享

1、简介1.1、案例简介本文将介绍&#xff0c;如何搭建培训机构-招生管理。1.2、应用场景根据意向信息站的收录信息&#xff0c;可批量导入意向信息&#xff0c;在意向信息站转为意向学员&#xff0c;转为意向学员后可进行报名收费成为正式学员。2、设置方法2.1、表单搭建1&…

从零实现深度学习框架:Seq2Seq从理论到实战【实战篇】

来源&#xff1a;投稿 作者&#xff1a;175 编辑&#xff1a;学姐 往期内容&#xff1a; 从零实现深度学习框架1&#xff1a;RNN从理论到实战&#xff08;理论篇&#xff09; 从零实现深度学习框架2&#xff1a;RNN从理论到实战&#xff08;实战篇&#xff09; 从零实现深度…

JUC-day01

JUC-day01 什么是JUC线程的状态: wait sleep关键字:同步锁 原理(重点)Lock接口: ReentrantLock(可重入锁)—>AQS CAS线程之间的通讯 1 什么是JUC 1.1 JUC简介 在Java中&#xff0c;线程部分是一个重点&#xff0c;本篇文章说的JUC也是关于线程的。JUC就是java.util .con…

活动预告 | GAIDC 全球人工智能开发者先锋大会

大会主题——“向光而行的 AI 开发者” 2023 全球人工智能开发者先锋大会&#xff08;GAIDC&#xff09; 由世界人工智能大会组委会、上海市经济和信息化委员会、上海市人才工作领导小组办公室及中国&#xff08;上海&#xff09;自由贸易试验区临港新片区管理委员会指导&…

【Java集合类】HashMap(二)- 设计要点

本章将开始探讨JDK中的HashMap&#xff0c;包括HashMap如何避免和解决上一章所说的散列冲突问题&#xff0c;以及Java 8对HashMap的改进 避免散列冲突- 散列函数设计 String.hashcode() Object.hashCode()方法用于返回当前对象的散列值。Object类中也约定了&#xff0c;重写…

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

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

提取括号中的内容

正则能解决不嵌套的括号内容提取问题遇到一个问题&#xff0c;就是需要提取字符串中每一个中括号里的内容&#xff0c;在网上搜了一下&#xff0c;发现用正则表达式(\[[^\]]*\])可以提取中括号中的内容&#xff0c;以下面文本为匹配对象&#xff1a;PerformanceManager[第1个中…