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 ...
随机推荐
- LN : leetcode 486 Predict the Winner
lc 486 Predict the Winner 486 Predict the Winner Given an array of scores that are non-negative inte ...
- ["1", "2", "3"].map(parseInt)
为什么["1", "2", "3"].map(parseInt) 为 1,NaN,NaN; parseInt() parseInt() 函数 ...
- Android学习笔记--Intent
Intent是android四大组件之间交互的一种重要方式.Intent可以指明当前要执行的动作,也可以指明要传递的数据.Intent可以用来启动活动,启动服务,发送广播. Intent分为两种:1. ...
- OCP 11g 第一章练习
练习 1-1 研究所在环境的DBMS 这是一个书面练习,没有具体的解决方案. 确定自己所在环境使用的应用程序, 应用服务器 , 和数据库. 然后集中精力研究数据库, 体验一下数据库的规模和忙碌程度. ...
- Struts2 前端与后台之间传值问题
老是被前端与后台之间的传值给弄糊涂了,特此写一篇blog进行总结. 一. 前端向后台传值 (1)属性驱动 属性驱动是指在Action类里,包含表单里对应的字段(字段名称一样),同时设置对应的gette ...
- sqlserver2012 offset
/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public Lic ...
- IE11/Flash页游白屏怎么办!立刻开启IE大地址模式!缓解浏览器白屏问题
您是否经常发现IE白屏了,具体表现为点开新网页时无法显示,只能切换标签,用任务管理器一看,内存1.2G之多. 这是因为IE11可能有内存泄露问题,内存不断增长以至于无法申请新的内存,于是IE就完蛋了! ...
- dmesg -检测和控制内核环缓冲
NAME dmesg - print or control the kernel ring buffer 总览 dmesg [ -c ] [ -n 级别 ] [ -s 缓冲区大小 ] 描述 dmesg ...
- this.$emit('on-select-change' emit里面不能写大写字母
this.$emit('on-select-change' emit里面不能写大写字母 刚试了下 也能写大写 但是 两边就都写一样就完了,就都写成带-的就完了
- Microsoft Windows Server
Microsoft Windows Server Microsoft Windows Microsoft Windows 是微软推出的个人版操作系统: Microsoft Windows Server ...