JVM类加载基本流程及双亲委派模型

1.JVM内存区域划分

一个运行起来的Java进程就是一个JVM虚拟机,这就需要从操作系统中申请一片内存区域。JVM申请到内存之后,会把这个内存划分为几个区域,每个区域都有各自的作用。

一般会把内存划分为四个区域 :方法区 (也称 "元数据区"),堆区 ,栈区 ,程序计数器。

(1)方法区:存储的内容是 "类对象"。

(2)堆区:new()出来的对象就存储在堆区。

(3)栈区:存储的内容一般是 一些 方法的形参,方法的返回值,局部变量。

(4)程序计数器:程序计数器中存放的是接下来要执行的指令的地址。

一个示例代码,看看每个变量存放在内存的哪个区域:

name是"static成员",是"静态变量",也就是**"类成员"** ,因此 该变量在 方法区。

age是"成员变量" ,new 出来的对象就会包含age这个属性,因此age变量在 堆区。

demo是**"局部变量"** ,是一个 "引用类型" 的变量,存放的是 对象的地址。通过demo变量能够找到Demo对象。因此,demo存储在栈区。

2.JVM类加载的基本流程

我们编写的Java代码会被编译成.class文件,一个Java程序想要运行起来,就得找到.calss文件,把.class文件中的内容 构造成 "类对象",保存到内存的方法区中。以上过程就是类加载的过程。

类加载的过程可以分成5个步骤:加载 ,验证 ,准备 ,解析 ,初始化。

(1)加载 :找到**.class文件**,打开文件 并读取文件的内容。

(2)验证 :.class文件是一个二进制文件,需要验证当前读取的格式是否符合要求。

(3)准备 :给类对象分配内存空间。

(4)解析 :针对类对象中包含的字符串常量进行处理,进行一些初始化操作。

(5)初始化 :对 类对象进行初始化,把类对象中的各个属性都设置好。以及涉及到的static成员,静态代码块等。

3.双亲委派模型

双亲委派模型 属于类加载流程中的第一步,也就是 "加载" 过程所涉及到的。这个模型 会根据 全限定类名 找.class文件。

JVM内置了三个 类加载器,分别为 BootStrap ClassLoader(爷)、Extension ClassLoader(父)、Application ClassLoader(子)。

在找.class文件时,会根据类的全限定类名,形如"java.lang.String",从类加载器中寻找该类。

(1)首先,会把Application ClassLoader 作为入口 ,开始执行查找的逻辑。但Application ClassLoader不会立即区扫描自己负责的目录**(搜索当前目录和第三方库对应的目录)** ,而是会把这个查找任务 交给自己的父加载器 Extension ClassLoader。

(2)那么Extension ClassLoader 加载器,也不会立刻去扫描自己负责的目录**(负责JDK中的一些扩展的库对应的目录)** ,而是把查找任务 交给自己的父加载器BootStrap ClassLoader。

(3)则BootStrap ClassLoader 也不想立刻去扫描自己负责的目录**(标准库的目录)**,于是尝试去把查找任务给到其它的类加载器,但是它没有"父亲",它只能亲自去扫描标准库的目录。

(4)"java.lang.String"能够在标准库中找到对应的.class文件,就可以打开并读取文件,那么寻找.class文件的任务就完成了。

(5)如果给定的类不是标准库的类 ,那么BootStrap ClassLoader在标准库中就找不到.class文件 ,还是会把查找任务交给**"孩子"**来执行。

(6)那么任务就会回到Extension ClassLoader 加载器,它就会扫描自己负责的扩展库的目录。如果找到了,查找.class任务就结束了;若没找到,还是把任务交给"孩子"执行;

(7)任务就又回到了Application ClassLoader 类加载器,它就会去扫描自己的当前目录和第三方库目录。若找到了,找.class文件任务结束;若没找到,就会抛出ClassNotFoundException。

以上寻找.class文件过程的模型就是**"双亲委派模型"** ,其实就是一个 查找优先级 的问题。率先在标准库中去查找.class文件,若没找到,就去扩展库中去找,再找不到,就去第三方库去找,还找不到,就会抛出异常。

相关推荐
学到老活到老11 小时前
方法执行完了,对象为什么还占着内存?
java·jvm
骑着蜗牛撵大象32718 小时前
四种库收进一个SQL编辑器(下):跨库取数、方言对齐与四库巡检的落地拆解
jvm·数据库·sql·编辑器·数据迁移·跨库查询
需要8261 天前
容器化 Java:镜像瘦身与 JVM 容器感知(cgroup)
java·开发语言·jvm
Pniubi2 天前
ConcurrentHashMap拆分线程池难点再讲
java·jvm
Irene19913 天前
Flink 学习日志 01:前端转大数据的实战避坑指南
java·jvm·flink
小天源3 天前
从 Nginx 日志到访问分析:轻量化网站监测服务的架构实践
jvm·nginx·网络安全·架构·网络监控
十年Java程序媛3 天前
JVM 内存区域与对象内存布局|new 对象底层流程,对象头 MarkWord 详解
java·jvm·spring boot
用户094248568033 天前
第2章:Windows、WSL2 与 Docker 环境搭建Redis
java·jvm
梅梅绵绵冰4 天前
JVM虚拟机
java·开发语言·jvm
十年Java程序媛4 天前
JVM 基础与 GC 垃圾回收详解|可达性分析、分代模型、垃圾收集器、STW
java·开发语言·jvm·spring boot·后端·面试