jvm的类加载器,类装载过程
混沌初开,在一片名为jvm的世界中,到处都是一片虚无,直到一个名为BootstrapClassLoader的巨人劈开了世界,据说它是由名叫C++的女神所造,它从一个叫做jre/lib的宝袋中拿出一把开天之斧ExtensionClassLoader,以及其他各种各样五颜六色的宝物,这些宝物撒落在混沌世界中,
化作了山山水水.紧接着,巨人又使用ExtensionClassLoader这把巨斧劈开了一个叫做jre/lib/ext的巨峰,那里瞬间迸发出了五颜六色的彩芒,彩芒四溅而去,让这个灰色的世界不再那么暗淡.紧接着,名为BootStrapClassloader的巨人又将ExtensionClassLoader变成了一把宝剑,这把宝剑
名为ApplicationClassloader(其父类是ExtensionClassLoader),它光芒四射,巨人将它放入了一个名为环境变量的水池中,那里有一个身上刻着CLASSPATH的金鱼,巨人用宝剑插到了金鱼的身上,金鱼的血在宝剑上流动着,最后形成了串字符 D://myJavaClass/.之后宝剑爆发出了万丈光芒,这些光芒映照在天空之上,形成了以下
这些字:
一个类的加载过程分为:加载,验证,准备,解析,初始化
加载:顾名思义,就是根据类的全路径将类文件以二进制流的形式加载到内存中,当然,除了本地加载之外,jvm也支持从网络远程加载(需要自己实现类加载器)以及运行时动态生成(典型例子:动态代理),加载阶段,其实是我们自定义类加载器时最好控制的阶段,因为我们可以在findClass()方法里拿到class文件的二进制流后,自定义业务逻辑
之后将二进制流传入defineClass()方法.
验证:查看class文件数据是否符合规范以及是否会对jvm造成影响如:该类是否继承了被final修饰的类,类型转换是否正常(如:一个int不能强转为String),对于其他类属性的访问是否有权限(private,public)
准备:为内存中的静态成员变量分配空间,并赋默认值,但如果是被final 修饰的静态成员变量且其是基本数据类型或者字符串类型.也就给其赋值,并将其值存入静态常量池中.(前提条件是有静态且被final修饰的成员变量,并且它的赋值是基本数据类型或者字符串)
解析:将类成员变量和方法的字面量转换为直接引用也就是内存地址的过程(字面量是什么意思呢?好比你有个helloWorld()方法,此时这个方法的字面量就是helloWorld,如果是int a = 0,那么0就是字面量,记住,是字面量,但它不是具体值,因为值其实是一个内存地址),解析阶段不是必需的,如果你的类里没有静态成员变量或者方法就不会进行
初始化:在这个阶段,静态成员变量会被赋上我们开发人员定义的值,而此时如果有静态成员变量引用的是其它类的成员变量,或者是方法,或者直接就是new了,那么此时会去初始化其它类,而如果其它类里有反引用了本类,并且是静态成员变量,那么会直接调用本类的
构造方法,对本类进行初始化,再回到其它类.当然,这一切的前提是,如果此类有父类的话,那么必先初始化其父类.
其实初始化并非是一定触发的,但有3种必定会触发初始化
1:使用new关键字
2:通过反射机制也就是newInstance(),这里再拓展一点反射获取Class对象的知识1:getClass()此方法是通过对象头里的Class指针拿到的对应此对象的Class对象,此方法不会触发初始化,因为你都拿到对象了啊,已经初始化过了.2:类名.class,不会触发初始化机制,因为在编译阶段的时候class引用就被添加到静态常量池里了.3:Class.forName(),会触发静态代码块,因为这个方法会将类装载到内存中,并且初始化.
3:执行main方法的类
还有几种不会触发,1:我之前说的被final修饰的静态成员变量,并且值是字符串或者基本数据类型
2:子类通过父类直接拿父类的静态成员变量,不会触发子类的初始化,会触发父类的初始化,哪怕是被final修饰的静态成员变量,不过请注意的是,子类会被装载到内存中的.
3:被数组定义的类,如:Student[] stuArr = new Student[2];
最后,拓展一个知识点,JAVA还有一个线程加载器,可以实现单个线程内加载类.也就是不同的线程可以加载相同的类
jvm的类加载器,类装载过程的更多相关文章
- 1.1 jvm核心类加载器--jdk源码剖析
目录 前提: 运行环境 1. 类加载的过程 1.1 类加载器初始化的过程 1.2 类加载的过程 1.3 类的懒加载 2. jvm核心类加载器 3. 双亲委派机制 4. 自定义类加载器 5. tomca ...
- JVM自定义类加载器加载指定classPath下的所有class及jar
一.JVM中的类加载器类型 从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器. 1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责 ...
- ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗
1.ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗? :当然是运行期间啊,我自己有个理解误区,改正后如下:编译期间编译器是不去加载类的,只负责编译而 ...
- 【深入理解JVM】类加载器与双亲委派模型 (转)
出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...
- 我把JVM的类加载器整理了一下
前言 之前去面试的时候面试官问了我关于关于JVM性能调优的问题,由于自己之前公司的项目里自己没有接触到JVM性能调优的相关问题(感觉这些都是公司架构师考虑的问题),所有面试官问的时候自己一脸懵逼, ...
- 1. JVM核心类加载器及类加载的全过程
运行环境: 下面说明一下我的运行环境.我是在mac上操作的. 先找到mac的java地址. 从~/.bash_profile中可以看到 java的home目录是: /Library/Java/Java ...
- JVM之类加载器上篇
首先我们先看一个示例程序: package com.tfdd.test; /** * @desc 类加载校验 * @author chenqm * @date 2016年2月2日 */ class S ...
- JVM之类加载器、加载过程及双亲委派机制
JVM 的生命周期 虚拟机的启动 Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由虚拟机的具体实 ...
- JVM(一)类加载器与类加载过程
JVM是面试必面的一个知识点,也是高级程序员必备的一个技能.以下是JVM整体核心内容,包括类加载系统,运行时数据区内部结构,执行引擎,本地方法接口. 首先来学习类的加载器,虚拟机把描述类的数据从Cla ...
随机推荐
- ASP.NET Web API 2 框架揭秘
这不是一本传统意义上的入门书籍 任何 —本书都具有对应的受众群体,所以我不得不将这句话放在最前面,并且希望所有 打算购买此书的读者能够看到.如果你之前对As氵NET W山API(或者AsPNET MⅤ ...
- SpringBoot 2.x (8):模板引擎
SpringBoot中有很多的starter:本质是多个JAR包集合 比如我们常用的: <dependency> <groupId>org.springframework.bo ...
- poj3280 Cheapest Palindrome
思路: 区间dp.添加和删除本质相同. 实现: #include <iostream> #include <cstdio> using namespace std; int n ...
- word打印小册子
使用联想m7250f打印册子,打印时设置该打印机属性为双面打印(手动),打印第一面后,将所有打印出的纸拿出并翻转使对应word中的第2页的打印纸朝外,之后将所有纸放入纸盒,再点击打印第二面即可.
- SQLite -分离数据库
SQLite -分离数据库 SQLite分离DTABASE语句用于分离和分离命名数据库从一个数据库连接之前附加使用附加语句.如果相同的数据库文件已附加多个别名,然后分离命令将断开只有名字和其他依附仍将 ...
- centos 更换yum源 (解决下载慢的问题)
先看有没有安装wget wget -V 如果没有执行 yum -y install wget 进行安装 然后进行配置的备份 mv /etc/yum.repos.d/CentO ...
- 7-Java-C(骰子游戏)
题目描述: 我们来玩一个游戏. 同时掷出3个普通骰子(6个面上的数字分别是1~6). 如果其中一个骰子上的数字等于另外两个的和,你就赢了. 下面的程序计算出你能获胜的精确概率(以既约分数表示) pub ...
- WPF知识点全攻略01- WPF相对WinFrom的优缺点
对比WPF和WinFrom前,先来了解下GUI现阶段在用的其他一些开发技术: MFC:微软基础类库,以C++的形式封装了Windows API,加上一些实用工具类. QT:奇趣科技开发的跨平台C++图 ...
- Java数据结构和算法(二)--队列
上一篇文章写了栈的相关知识,而本文会讲一下队列 队列是一种特殊的线性表,在尾部插入(入队Enqueue),从头部删除(出队Dequeue),和栈的特性相反,存取数据特点是:FIFO Java中queu ...
- function语句注意事项
function语句 在Javascript中定义一个函数,有两种写法: function foo() { } 和 var foo = function () { } 两种写法完全等价.但是在解析的时 ...