Java 细聊JVM之类加载器

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

什么是JVM

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

JVM所处的位置

JVM是运行在操作系统之上的,它与硬件没有直接的交互,但是它可以通过 native 本地方法调用硬件接口

JVM体系结构

类装载器

负责加载 class 文件,class 文件在文件开头有特定的文件标示,将 class 文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构并且 ClassLoader 只负责 class 文件的加载,至于它是否可以运行,则由 Execution Engine 决定。

特定的文件标示

众所周知,Java 的 logo是一杯cafe。使用 sublime  任意打开一个 class 文件,发现开头的前八个字母都是“cafe babe”,这就是 class 的标识,这也是作者詹姆斯•高斯林(James Gosling)在创作 Java 之初就用到了两个魔数。

方法区简单介绍

JVM 中的方法区,并不是用来存类里面方法的区域,它是用来存放类的描述信息,也就是放模板的地方。

 

分类

Java中类装载器总共分为两大类,四小类,加载顺序是自上到下依次加载。

虚拟机自带的加载器

  • 启动类加载器(Bootstrap)C++编写,是根加载器,最早加载 JVM 基础类,java.lang.*,java.uitl.* 等等
  • 扩展类加载器(Extension)Java编写,javax.* 的所有类都是使用这种加载器
  • 应用程序类加载器(AppClassLoader)Java也叫系统类加载器,加载当前应用的classpath的所有类。除上面两种的加载的类,其他的都属于这种。最简单的理解就是用户自定义的类,都属于应用程序类加载器

用户自定义加载器

继承 Java.lang.ClassLoader 的子类,用户可以定制类的加载方式

示例

public class ClassLoaderDemo {
	public static void main(String[] args) {
		Object object = new Object();
		//根据反射机制查找 Object 类加载器。因为 Object是JDK自带的类
		//所以是,启动类加载器(Bootstrap),但是因为他是C++编写,所以输出 null
		System.out.println(object.getClass().getClassLoader());
		
		ClassLoaderDemo classLoaderDemo = new ClassLoaderDemo();
		//这个对象是用户自定义编写的,所以他的加载器是 应用程序类加载器(AppClassLoader)
		System.out.println(classLoaderDemo.getClass().getClassLoader());
		
		System.out.println();
		
		//启动类加载器(Bootstrap) 输出 null
		System.out.println(classLoaderDemo.getClass().getClassLoader().getParent().getParent());
		//扩展扩展类加载器(Extension)
		System.out.println(classLoaderDemo.getClass().getClassLoader().getParent());
		//应用程序类加载器(AppClassLoader)
		System.out.println(classLoaderDemo.getClass().getClassLoader());
	}
}

结果

双亲委派机制

 当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object对象。  

沙箱安全

假如我们不小心写了一个 String 类,包路径是 java.lang.String ,和JDK一样,运行以下看看结果

package java.lang; //包名和 String 一样

public class String {
	//主方法
	public static void main(String[] args) {
		System.out.println("String");
	}
}

结果

报的错误是找不到 main 方法,原因就是Java采用双亲委派机制和沙箱安全机制。当一个类被加载,首先是从启动类加载器(Bootstrap)加载,然后是扩展类加载器(Extension),最后才是应用程序类加载器(AppClassLoader)。所以这里加载的是 rt.jar 中的String类,所以没有 main 方法。

基本组件

1.类加载器结构

它防止了恶意代码去干涉善意的代码,这是通过为不同的类加载器装入的类提供了不同的命名空间来实现的,命名空间互相独立。
它守护了被信任类库的边界,这是通过分别使用不同的类加载器装载可靠的包和不可靠的包来实现的。
它将代码归入某类(命名空间),该类确定了代码可以执行哪些操作,一个保护域定义了这个代码在运行时将得到的权限。

2.class文件效验器

  • class文件结构的检查
  • 类型数据的语义检查
  • 字节码验证
  • 符号引用的检查
  • 二进制兼容

3.内置于JAVA虚拟机(及语言)的安全特性

  • 类型安全的引用转换
  • 结构化的内存访问(无指针算法)
  • 自动垃圾收集(不必显示的释放被分配的内存)
  • 数组边界检查
  • 空引用检查

4.安全管理器及API

虽然安全管理器是JAVA安全模型最大的优点之一,但是也有一个潜在的弱点。编写一个安全管理器是一项负责的任务,并可能导致出错。在实现安全管理器的check方法时,任何错误都将变成运行时的安全漏洞。

5.代码签名和认证

JVM的三种类加载器 java程序员有一段时间了,但是对JVM是怎么加载类的一直是懵懵懂懂,看了一些博客,现把自己对JVM类加载器的一些理解和大家分享一下。 咱们的类经过javac编译后,生成.class文件保存下来,然后经过类加载器加载类至内存,生成java.lang.Class类的实例,这个实例就是程序访问这个类的入口,通过这个class实例的newInstance方法即可得到这个类的实例... 阅读详情

相关推荐

JVM系列之类加载器

前言 上节我们介绍了类加载的时机和过程,对类加载有了个初步的认识,上节我们有不断提到一个东西:类加载器,那么什么是类加载器?又有哪些类加载器类加载器之间的联系等等一些问题,今天我们将会围绕这些点展开,那么,开始我们今天的JVM之旅吧。 什么是类加载器? 把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部实现,以便让应用程序自己决定如何获取所需要的类,实现该动作的代码模块就被称为“类加载器”。 类与类加载器的联系 类加载器用于实现类的..

吭哧吭哧快乐的小牛码 2万+

JVM详解

JVM探究 请你谈谈对JVM的理解? java8虚拟机和之前的变化更新 什么是OOM(内存溢出)? 什么是栈溢出(stackOverFlowError)? 怎么分析? JVM常用的调优参数有哪些? 内存快照如何抓取? 怎么分析Domp文件 ? 知道吗? 谈谈JVM中,类加载器你的认识? 1.jvm的位置 jvm运行在操作系统之上,java程序运行在jvm上,jvm用C写的 jre包含jvm 2.jvm的体系结构 方法区属于一个特殊的堆,属于堆里的一块。 jvm调优大部分是在调堆。 3.类加载器

qq_43842093的博客 1511

JVM基础之类加载器详解

开始 本文我整理了一些JVM类加载器相关的面试高频知识点,方便同学们复习。 在详了解JVM知识点之前,我们先引入以下基础的经典面试题: 谈谈你对Java的理解 平台无关性,一次编译到处运行。 GC垃圾回收机制:Java无需像C++一样手动管理内存。 Java的语言特性:泛型、反射、lambda表达式等。 面向对象:包括封装、继承、多态。 Java自身类库如:集合、并发库、网络库以及IO流。 异常处理。 Java 和 C++的区别 Java不提供指针直接访问内存,程序的内存更加安全。

a6636656的博客 1150

JVM组件

前言: JVM(Java Virtual Model)Java虚拟机模型与JMM(Java Memory Model)不同。 JVM组件 JVM的主要组成部分包括:类加载引擎,运行时数据区,执行引擎,本地库接口。JVM结构图如下所示: 组件的作用: 首先通过类加载引擎将JAVA代码转换成字节码,然后运行时数据区会将字节码加载到内存中,由于字节码只是JVM的一套规范指令集,并不能直接交给底层操作系统执行执行,这里需要特定的命令解析器执行引擎来解析,在解析的过程会调用其他语言的本地库接口来实现整个程序的功能。

向往的博客 647

JAVA学习之JDK,JRE和JVM

1.JVM--Java Virtual Machine(Java虚拟机) 1.1 定义 JVM提供了执行Java字节码的运行环境,它还可以运行用其他语言编写并编译成字节码的程序。它只是一组规范,在物理上并不存在。JVM能够:加载代码、验证代码、执行代码并提供运行环境。 1.2 JVM的结构 Classloader 类加载器JVM的一个子系统,用于加载类文件。每当我们运行Java程序时,它首先由类加载器加载. Class Area Class Area存储每类结构,如运行时常量池...

qq_40400633的博客 253

JVM内幕:Java虚拟机详解

这篇文章解释了Java 虚拟机(JVM)的内部架构。下图显示了遵守 Java SE 7 规范的典型的 JVM 核心内部组件。 上图显示的组件分两个章节解释。第一章讨论针对每个线程创建的组件,第二章节讨论了线程无关组件。线程 JVM 系统线程 每个线程相关的 程序计数器 栈 本地栈 栈限制 栈帧 局部变量数组 操作数栈 动态链接 线程共享 堆 内存管理 非堆内存 即时编译 方法区 类文件结构 类加

charming的专栏 1073

class文件魔数CAFEBABE的由来

Java中class文件的前四个字节为什么是 CAFEBABE? 是谁定义的? Java编程语言之父,詹姆斯•高斯林(James Gosling),曾这样说过: 关于这一点,我很抱歉。我以前并不知道有 NeXT connection。这些有趣的十六进制数(HEX words)可能是匹配的来源. 至于在Java中使用CAFEBABE作...

weixin_33698823的博客 920

JVM类加载器机制

JVM类加载器机制 目录 JVM类加载器机制 01 怎么获取类加载器?哪几种类加载器 02 各个加载器加载的路径? 01 怎么获取类加载器?哪几种类加载器 BootStrapClassLoader 引导类加载器 ExtClassLoader 扩展类加载器 AppClassLoader应用级别的类加载器 UserD...

DeanKano的博客 51万+

Java基础之类加载器

Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用,理解它有利于我们写出更优雅的程序。本文首先介绍了Java虚拟机加载程序的过程,简述了Java类加载器的加载方式(双亲委派模式),然后介绍了几种常见的类加载器及其适用场景,最后则一个例子展示了如何自定义类加载器。 基本概念 基本文件类型和概念 常见概念介绍: java源文件(.java):.javaJava的源文件后缀,里面存放程序员编写的功能代码,只是一个文本文件,不能被java虚拟机所识别, 但是java语法有

m0_68064743的博客 1万+

jvm之类加载器

类加载器 注意图中的类加载器之间并不是继承关系,而是包含关系。 根类加载器类加载器(BootstrapClassLoader):负责加载存放在JDK/jre/lib下的指定的jar,也可以使用-Xbootclasspath参数指定哪些jar要使用根类加载器加载。 下面的代码将会打印BootstrapClassLoader以及根类加载器负责加载哪些jar: System.out.println("BootstrapClassLoader:" + String.class.getClassLoader()

morris 1万+

JVM 之类加载器

JVMJava Virtual Machine)是一个可以执行 Java 字节码文件(即 .class 文件)的虚拟机进程。当 Java 源文件能被成功编译成 .class 文件,就能在不同平台上的不同版本的 JVM 运行,因为 JVM 能将相同的 .class 文件解释称不同平台的机器码。正是因为 JVM 的存在,Java 被称为与平台无关的语言。一般而言,.java 文件经过编译后会得到 .class 文件,而将这个文件加载到内存之前需要先通过类加载器,先简单过一下图:类加载的过程为: 加载–>连接(

大数据的奇妙冒险 1754

JVM之类加载器

文章目录JVM整体结构1、类加载器子系统作用2、类的加载过程2.1、Lodading加载2.2、Linking链接2.2.1、验证(Verify)2.2.2、准备(Prepare)2.2.3、解析(Resolve)2.3、Initialization初始化3、类加载器的分类3.1、启动类加载器(引导类加载器,Bootstrap ClassLoader)3.2、扩展类加载器(Extension ClassLoader)3.3、应用程序加载器(系统类加载器,AppClassLoader)3.4、用户自定义加载器

从基础到源码解析的学习记录 545

JVM进阶之类加载器详解

类加载器详解一、类加载器概述1.作用2.分类3.重要性4.命名空间5.特性二、类加载器分类1.基本概述2.引导类加载器3.扩展类加载器4.系统类加载器5.自定义类加载器三、类加载器测试1.获取类加载器方式2.获取类加载器示例四、类加载器解析1.ClassLoader关继承关系图2.ClassLoader中的核心方法3.Class.forName和ClassLoader.loadClass的区别 一、类加载器概述 1.作用 类加载器JVM执行类加载机制的前提,它是Java的核心组件,所有的类都是由类加载器

ProChick's Blog 1386

JVM底层之类加载器详解

一、类加载器 JVM中有两种类型的类加载器,由C++编写的及由Java编写的。除了启动类加载器(Bootstrap Class Loader)是由C++编写的,其他都是由Java编写的。由Java编写的类加载器都继承自类java.lang.ClassLoader。 JVM还支持自定义类加载器。 各种类加载器之间存在着逻辑上的父子关系,但不是真正意义上的父子关系,因为它们直接没有从属关系。 1.1、启动类加载器 因为启动类是由C++编写的,所以当我们通过Java程序看显示的是null。 启动类加载器不像其

沮丧的南瓜 1370

JVM之类加载器ClassLoader

Java虚拟机之类加载器ClassLoader 本文目录 JVM简介 类加载器解析 1. JVM简介 ①. JVM是运行在操作系统之上的,它与硬件没有直接的交互 ②. JVM体系结构概览 注: 2. 类装载器解析 ①. 类装载器负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Exe...

努力努力再努力L 467

深入浅出JVM(八)之类加载器

什么是类加载器?类加载器通过类的全限定类名进行类加载机制从而生成Class对象Class对象中包含该类相关类信息,通过Class对象能够使用反射在运行时阶段动态做一些事情显示加载与隐式加载类加载器有两种方式进行加载,一种是在代码层面显示的调用,另一种是当程序遇到创建对象等命令时自行判断该类是否进行过加载,未加载就先进行类加载显示加载:显示调用ClassLoader加载class对象隐式加载:不显示调用ClassLoader加载class对象(因为虚拟机会在第一次使用到某个类时自动加载这个类)

关注菜菜的后端私房菜,获取更多技术干货~ 1145
上一篇: Java 死锁的概念及排查
下一篇: Hadoop配置安装指南
楚瑞涛
博客等级 码龄9年 57粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值