鸟菜Java基础篇_2012_8_11(classloader)
2012-08-11 23:01
381 查看
接触Java以来,通常是用的多,深入的少,这绝对不是一个鸟菜可以提升自己的好习惯。因此,在这里就稍微深入一下。
套用业外人士范伟大叔的一句话:我既想知道这是怎么来地,我也想知道这是怎么没地!
所以,从一切的根源出发,看看java文件是怎么载入的,怎么初始化的,怎么使用的,最后怎么销毁的。本章我们讨论一下classloader,还是一样,作为鸟菜,先会用,再把它用好。
0. 一个java文件(静止的类)想要变成运行时可以生成对象的(鲜活的类),要经历哪些过程呢?大体上来说,首先是编译器编译,将.java文件编译成.class文件,也就是字节码文件;然后,jvm将.class文件加载,之后将二进制数据合并到jre中,就是链接阶段;当显示或隐式生成/调用用该类及其对象时,类内成员进行初始化。完成这些步骤,就可以使用该类或者生成对象了。大体过程如此,细节我们慢慢谈。
1.talk is cheap,show me the code -----linux
我们通过一个类加载的过程,来说明classLoader工作原理。 类很简单,看代码:
Bootstrap ClassLoader 负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
Extension ClassLoader 负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
App ClassLoader 负责加载当前java应用的classpath中的所有类。
jvm加载类很有意思,每次都是找他的父类,先看父类是否已经加载,直到Bootstrap;如果还没找到,再返回子类继续找。
这样做的主要目的:保证优先级高的类被优先加载,比如系统级别的rt.jar等。
2.开始展示一下SearchClassLoader类是如何加载的
断点classloader.class中loadClass方法:
接下来,确认该类是否已经被当前classloader加载过
若当前classLoader并没有加载该类,则寻找其父加载器类
接下来:
如果都没找到,进入BootstrapClassLoader
还是没找到,要抛出异常
抛异常:
接下来:进入了URLCLassLoader
找到后:返回该类
到此,searchclassLoader类已经加载已经完成,需要后续的链接和初始化:
下面是类型检查:
然后:对于每个通过当前classloader加载的类,加载器都会保存记录。
然后:进行类的载入,将字节码转换存储在byte[]b中
然后:对于成功载入的类,都会对应生成一个Class.class类的实例!这个实例中记录了载入类的所有信息!因此可以通过反射机制生成该类,这个以后再说。
以上就是一个类加载链接并初始化全过程,更多细节还需要进一步调试,了解这个几个classloader的加载顺序是非常重要的,
我们日常见到的补丁安装/热部署等等都和类的加载顺序有密切关系。
明天我们会继续讨论classloader,我们接下来要尝试编写自己的classloader加载类。
更多的细节,明天继续。
最后附上一副流程图吧,这个看起来更清晰:
流程图转自:/article/4172131.html 觉得还是流程图更清晰一些
See you !
套用业外人士范伟大叔的一句话:我既想知道这是怎么来地,我也想知道这是怎么没地!
所以,从一切的根源出发,看看java文件是怎么载入的,怎么初始化的,怎么使用的,最后怎么销毁的。本章我们讨论一下classloader,还是一样,作为鸟菜,先会用,再把它用好。
0. 一个java文件(静止的类)想要变成运行时可以生成对象的(鲜活的类),要经历哪些过程呢?大体上来说,首先是编译器编译,将.java文件编译成.class文件,也就是字节码文件;然后,jvm将.class文件加载,之后将二进制数据合并到jre中,就是链接阶段;当显示或隐式生成/调用用该类及其对象时,类内成员进行初始化。完成这些步骤,就可以使用该类或者生成对象了。大体过程如此,细节我们慢慢谈。
1.talk is cheap,show me the code -----linux
我们通过一个类加载的过程,来说明classLoader工作原理。 类很简单,看代码:
public class SearchClassLoader { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SearchClassLoader s = new SearchClassLoader(); } }看classloader.class代码之前,几个用到的classLoader需要简单说一下:
Bootstrap ClassLoader 负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
Extension ClassLoader 负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
App ClassLoader 负责加载当前java应用的classpath中的所有类。
jvm加载类很有意思,每次都是找他的父类,先看父类是否已经加载,直到Bootstrap;如果还没找到,再返回子类继续找。
这样做的主要目的:保证优先级高的类被优先加载,比如系统级别的rt.jar等。
2.开始展示一下SearchClassLoader类是如何加载的
断点classloader.class中loadClass方法:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }首先:jvm从调用AppClassLoader开始,寻找其父类,试图加载SearchClassLoader.class
接下来,确认该类是否已经被当前classloader加载过
若当前classLoader并没有加载该类,则寻找其父加载器类
接下来:
如果都没找到,进入BootstrapClassLoader
还是没找到,要抛出异常
抛异常:
接下来:进入了URLCLassLoader
找到后:返回该类
到此,searchclassLoader类已经加载已经完成,需要后续的链接和初始化:
下面是类型检查:
然后:对于每个通过当前classloader加载的类,加载器都会保存记录。
然后:进行类的载入,将字节码转换存储在byte[]b中
然后:对于成功载入的类,都会对应生成一个Class.class类的实例!这个实例中记录了载入类的所有信息!因此可以通过反射机制生成该类,这个以后再说。
以上就是一个类加载链接并初始化全过程,更多细节还需要进一步调试,了解这个几个classloader的加载顺序是非常重要的,
我们日常见到的补丁安装/热部署等等都和类的加载顺序有密切关系。
明天我们会继续讨论classloader,我们接下来要尝试编写自己的classloader加载类。
更多的细节,明天继续。
最后附上一副流程图吧,这个看起来更清晰:
流程图转自:/article/4172131.html 觉得还是流程图更清晰一些
See you !
相关文章推荐
- 鸟菜Java基础篇_2012_8_4
- Java多线程系列--“基础篇”11之 生产消费者问题 (r)
- android基础篇------------java基础(11)(文件解析xml and Json )
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- android基础篇------------java基础(11)(文件解析xml and Json )
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java多线程系列--“基础篇”11之 生产消费者问题
- Java笔记11:RETURN注意事项
- Java初学者必知:Java语言的11大特点
- 【Java 基础篇】【第三课】表达式、控制结构
- java 类加载器ClassLoader详解(二)——获取资源(getResource)
- (11)Java笔记11之继承
- 黑马程序员—11—java基础:有关线程通信的学习笔记和学习心得体会
- java学习之旅38--面向对象_11_继承_基本概念
- java集合11--HashTable源码详解
- 蓝桥杯2012预赛java高职题分析
- 一个计算机专业学生几年的编程经验汇总 (该系列一共 11 篇,看完之后,java 基础绝对有不小的提升!)
- 【转】深度分析Java的ClassLoader机制(源码级别)