我们都知道以 .java 结尾的 Java 源文件,经过编译之后会变成 .class 结尾的字节码文件。JVM 通过类加载器来加载字节码文件,然后再执行程序。

什么时候加载一个类

那么,什么时候类加载器会加载一个类呢?用到这个类的时候,JVM的类加载器就会加载这个类。用到这两个字说起来很抽象,我用代码和图例来说明。

有下面这样一段代码,一个类EmergencyPlan,里面有一个main()函数,main()函数做的事情是创建了一个 Account 对象。

public class EmergencyPlan {
public static void main(String[] args) {
Account account = new Account();
}
}

我们应该知道运行 JVM 就相当于启动了一个 Java 的进程,它会从程序的主函数,即main()函数开始执行。所以类加载的步骤是这样的:

  1. 先加载主函数所在的类EmergencyPlan
  2. 由于EmergencyPlan使用了Account,所以继续加载Account

准备和初始化的区别

类加载机制总共有这样7个步骤:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载。接下来先把每个阶段在做什么讲一下,再着重对比一下准备阶段和初始化阶段。

  • 验证阶段:验证字节码文件是否符合JVM的规范。这挺好理解,万一字节码文件被修改过,JVM压根无法执行咋办。所以加载之后先验证一下。
  • 准备阶段:为类分配内存空间,为变量赋初值。
  • 解析阶段:符号引用替换为直接引用。
  • 初始化阶段:执行初始化代码,new对象;执行static代码块;父类没有初始化要先初始化父类。

用代码和画图来说明一下准备阶段和初始化阶段。

public class EmergencyPlan {
public static int id
= Configuration.getInt("plan_id");
}

这段代码说的是EmergencyPlan这个类有一个变量id,通过getInt()为其赋值:

  • 准备阶段会为id开辟一个内存空间,但不会执行赋值操作,仅仅是赋予一个初值0。
  • 初始化阶段才会执行getInt()为变量id初始化值。

类加载的过程就变成了下图所示的样子:

类加载器和双亲委派模型

JVM进行类加载是通过类加载器完成,类加载器是一种亲子层级结构的模型。Java里面的类加载器有这样几种:

  • 启动类加载器。加载 JDK 中 lib 目录中 Java 的核心类库,即$JAVA_HOME/lib目录。
  • 扩展类加载器。加载 lib/ext 目录下的类。
  • 应用程序类加载器。加载我们写的应用程序。
  • 自定义类加载器。根据自己的需求定制类加载器。

那什么是双亲委派模型呢?类加载器是一种亲自层级结构,就像下图所示:

比如要加载上面的EmergencyPlan类,应用程序类加载器会先问它的父亲扩展类加载器,你能帮我加载么?扩展类加载器会再问它的父亲启动类加载器,你能帮我加载么?

显然EmergencyPlan是一个应用程序类。启动类加载器会告诉扩展类加载器,你自己去加载;扩展类加载器就会告诉应该程序类加载器,你自己去加载。最后,应用程序类加载器就自己加载了EmergencyPlan

流程图总结

最后来在类加载的流程图上,把双亲委派模型也添加上去。

图解JVM类加载机制和双亲委派模型的更多相关文章

  1. Java类加载机制以及双亲委派模型

    一.Java类加载机制 1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允 ...

  2. java虚拟机(二)--类加载机制和双亲委派模型

    一.类的生命周期 加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(Initialization).使用(Using).卸 ...

  3. JVM类加载器以及双亲委派模型

    从java开发人员的角度来看,类加载器可以分为3种: 1.启动类加载器(Bootstrap ClassLoader),负责将存放在<JAVA_HOME>\lib目录中,或者被-Xbootc ...

  4. JVM类加载过程与双亲委派模型

    类加载过程 类加载过程为JVM将类描述数据从.class文件中加载到内存,并对数据进行解析和初始化,最终形成被JVM直接使用的Java类型.包含: 加载:获取该类的二进制字节流,将字节流代表的静态存储 ...

  5. java虚拟机类加载机制和双亲委派模型

    java虚拟机类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型. 类的生命周期是从类被加载到虚拟机内存中,到卸 ...

  6. JVM——类加载器的双亲委派模型

    类加载器双亲委派模型,如下图所示: 双亲委派模型的工作过程 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此 ...

  7. jvm类加载器和双亲委派模型

    类加载器按照层次,从顶层到底层,分为以下三种:  (1)启动类加载器(Bootstrap ClassLoader)   这个类加载器负责将存放在JAVA_HOME/lib下的,或者被-Xbootcla ...

  8. 类文件的结构、JVM 的类加载过程、类加载机制、类加载器、双亲委派模型

    一.类文件的结构 我们都知道,各种不同平台的虚拟机,都支持 "字节码 Byte Code" 这种程序存储格式,这构成了 Java 平台无关性的基石.甚至现在平台无关性也开始演变出 ...

  9. 【深入理解JVM】类加载器与双亲委派模型

    原文链接:http://blog.csdn.net/u011080472/article/details/51332866,http://www.cnblogs.com/lanxuezaipiao/p ...

随机推荐

  1. 菜鸟系列Golang学习 — 切片

    切片简介 切片也是一种数据类型,在Golang中,切片底层基于数组实现的. 我们定义切片如下 var slice []int 切片之所以出现,是为了更好的利用资源,管理数据,如果使用数组,则我们一开始 ...

  2. Markdown 语法简要规则

    Markdown简介 Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的语法十分简 ...

  3. 【JavaScript】DOM之Document对象

    JS(JavaScript) 一.Document对象 1.Document对象是什么 Document对象 是DOM的基本规范也是重要的对象之一,以访问,更新页面内容的属性和方法通过conslie. ...

  4. 前端每日实战:74# 视频演示如何用纯 CSS 创作一台 MacBook Pro

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/MXNNyR 可交互视频 此视频是可 ...

  5. 搭建Flutter开发环境需要注意的几个小Tips

    目录 下载SDK 安装 Android Stdio + SDK + tool SDK + 创建模拟器 + 插件(flutter和dart) Xcode + cocoapods VSCode + Flu ...

  6. 谈谈集合.Queue

    之前说到,Java中集合的主要作用就是装盛其他数据和实现常见的数据结构.所以当我们要用到"栈"."队列"."链表"和"数组&quo ...

  7. 你会无聊到把Administrator用户禁用,并且自己创建的用户搞到消失掉还有Administrator用户被禁吗。。。。。

    2020年3月17日20:07:00 如文章标题哈,就是这么任性,无奈 事件起因:因为要部署项目,并且需要将线上的Oracle数据库导入到本地Oracle数据库中突然发现使用 sqlplus 连接数据 ...

  8. 题解 NOIP2018【赛道修建】—— 洛谷

    这道题有一点点树上dp的意思(大佬轻喷 我刚拿到这道题的时候毫无头绪,只知道这道题要二分答案 为什么是二分答案??? 题目: 目前赛道修建的方案尚未确定.你的任务是设计一 种赛道修建的方案,使得修建的 ...

  9. 原生Canvas循环滚动弹幕(现金红包活动带头像弹幕)

    效果 gif有些糊,可以 在线预览 实现关键点 requestAnimationFrame 循环帧: 绘制单条弹幕,画框子 -> 画头像 -> 写黑色的字 -> 写红色的字, mea ...

  10. Python3 + requests + unittest接口测试

    一.缘 起 笔者最近完成了基于Python3 + requests + unittest的接口测试脚本,故在此做一下记录,于己为复盘,于彼为学习和参考 二.思 路 接口测试无非三步: 首先,造数据 - ...