近期学习java的classloader(类加载器),有必要记录下,好记性不如烂笔头,这里略去代码测试部分,纯粹记录脑中所想,如有纰漏、错误请大家及时提出,也是帮我提高。
系统类加载器:
当java虚拟机(jvm.dll)启动后,会创建三个类加载器BootStrapClassLoader、ExtClassLoader、AppClassLoader,它们是java虚拟机的一部分,一直逗留在内存中,直到java虚拟机终止才会在内存中消失,它们都有自己的管辖目录范围,在管辖内寻找类(.class文件)来加载。
BootStrapClassLoader:c++编写,在java中表现形式为null。
ExtClassLoader:java编写,源代码在sun.misc.Launcher类中,它是一个内部类。
AppClassLoader:java编写,源代码也在sun.misc.Launcher类中,它也是一个内部类。
简单理解,ExtClassLoader和AppClassLoader被设计成单例模式,在内存中分别只有一个对象。
用户创建类加载器:
用java编写的类加载器都要直接或者间接继承类java.lang.ClassLoader,包括用户(用户指程序员)自己编写的,也包括系统类加载器ExtClassLoader和AppClassLoader。
- 父子委托模式是在java.lang.ClassLoader中的loadClass方法描述的,ExtClassLoader和AppClassLoader在加载类的时候也会调用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;
}
}
-
java.lang.ClassLoader的构造函数可以用来设置加载器的父亲(parent),不带参数的构造函数会自动把AppClassLoader设置为parent,带参数的构造函数可以根据参数设置parent,子类最好覆盖java.lang.ClassLoader的构造函数,下面是java.lang.ClassLoader的构造函数:
protected ClassLoader() {
this(checkCreateClassLoader(), getSystemClassLoader());
}
protected ClassLoader(ClassLoader parent) {
this(checkCreateClassLoader(), parent);
}
具体细节查看javadoc或者sourcecode.
-
按javadoc中描述,继承java.lang.ClassLoader后需要覆盖findClass方法,实现具体的加载类的过程,用户编写的类加载器也可以有自己的管辖目录范围,可以在覆盖findClass方法时定义。
-
java.net.URLClassLoader 是系统API提供的可直接使用的类加载器,它继承了java.lang.ClassLoader,也覆盖了构造函数,也覆盖了findClass方法。
ExtClassLoader和AppClassLoader都是继承了java.net.URLClassLoader来扩展自己的功能的。
-
绕开父子委托模式 我个人简单认为可以把parent设置成null或者直接使用findClass方法,避免使用直接继承类java.lang.ClassLoader的loadClass方法。
类加载器有两种,一种是系统类加载器(在内存中只有一份),另一种是用户自己定义类加载器(在内存中可以有很多份,根据new的次数)。
class文件在内存中的形态:
同一个class文件可以被不同的类加载器对象加载,每个类加载器对象只能对它加载一次(如果用loadClass方法的话)。这样看来class文件在内存中可能会有很多份,每一份都是一个class对象,大家都知道在new的时候就是根据这个class对象为模板创建对象的,当内存里有很多class对象的时候,new的时候会根据系统类加载器(BootStrapClassLoader、ExtClassLoader、AppClassLoader)加载的那个class对象为模板创建对象,效果和其他份class对象的newInstance()一样。class对象newInstance()的时候返回一个Object对象,如果对它向下转型为具体类的时候可能会出现奇怪的现象,见 http://www.iteye.com/problems/77669 在向下转型的时候,对比的是class对象是否相等,不同的类加载器加载的class对象是不同的,是各占一个内存空间的,所以出现连接中的问题。
上面的内容都是根据现象推出来的,还没有足够的证据支持,下一步继续学习jvm规范,希望能找到依据,内部实现机制还是很多不了解。
分享到:
相关推荐
学习JDBC第一个练习,封装JDBC的源代码,初步封装,通过反射Class实例,类文件加载阶段执行,而且只执行一次的作封装,如:获取类加载器,然后通过类加载器获取输入数据流对象,创建Properties实例对象,加载配置项文件,将...
这个压缩包“matlab神经网络和优化算法:1感知器神经网络初步学习程序.zip”显然包含了一个关于感知器网络的初学者教程。 感知器神经网络,最初由Frank Rosenblatt在1957年提出,是一种最简单的前馈神经网络,由...
在这个"入门MATLAB神经网络和优化算法专题:1 感知器神经网络初步学习程序"的压缩包中,我们将会探讨感知器神经网络的基础知识以及如何在MATLAB中实现它。 感知器是神经网络的最简单形式,由Frank Rosenblatt于1957...
在进行深度学习模型构建时,我们通常会用到`nn.Module`,它是PyTorch中的神经网络模块类。你可以通过定义`__init__`和`forward`方法来创建自定义的网络结构。在`__init__`中初始化网络层,如卷积层(`nn.Conv2d`)、...
初步学习jQuery的概念及选择器 jQuery是一个功能强大且流行的JavaScript库,它提供了许多实用的方法来简化网站开发和交互设计。 本文将对jQuery的基本概念和选择器进行介绍,旨在帮助读者快速掌握jQuery的基础知识...
`cv2.CascadeClassifier`类可以加载预训练的级联分类器XML文件进行物体检测。 6. **图像变换**:包括几何变换(如缩放、旋转、仿射变换)和光照变换(如直方图均衡化)。`cv2.warpAffine()`和`cv2.equalizeHist()`...
### 新人学习Autoware代码初步指导 #### 一、Autoware.AI简介与系统架构 Autoware.AI是一款革命性的"All-in-One"开源自动驾驶软件,它在全球范围内首次实现了自动驾驶技术的全面开源化。该软件运行于ROS1操作系统...
"Android高级应用源码-图片加载器.zip"提供的就是一个针对这一需求的解决方案。这个压缩包包含了Android图片加载器的源代码,可以帮助开发者深入理解图片加载的机制,并为自己的项目提供参考。 首先,我们要了解...
QT Quick 的初步学习主要包括以下几个方面: 1. **QML 基础**: - QML 提供了一种简洁的方式来定义 UI 元素,如按钮、文本框等,通过 JSON 样式的语法来创建和配置对象。 - QML 文件通常以 `.qml` 结尾,可以包含...
在本压缩包“matlab神经网络和优化算法:1 感知器神经网络初步学习程序.zip”中,我们主要探讨的是使用MATLAB环境下的神经网络模型,特别是感知器神经网络的基础知识及其应用。MATLAB作为一款强大的数学计算软件,为...
**jQuery 初步入门学习小资料** jQuery 是一个广受欢迎的 JavaScript 库,它极大地简化了 JavaScript 的使用,使得开发者可以高效地实现网页交互、动画效果以及与服务器的数据通信。这个压缩包文件提供了关于 ...
ClassLoader的层次结构包括Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和App ClassLoader(应用程序类加载器),它们共同负责加载不同级别的类。开发者还可以自定义类加载器,以...
8. 机器学习与深度学习:OpenCV集成了传统的机器学习库(如SVM、决策树等)以及深度学习框架(如DNN模块,支持TensorFlow、Caffe等模型的加载和推理)。 在实际项目中,OpenCV可以通过Python、Java、C++等多种编程...
这一周的实习让我对JAVA开发有了更深入的理解,特别是对Java虚拟机(JVM)和类加载器(ClassLoader)机制有了初步的认识。 Java虚拟机是Java语言运行的基础,它负责管理程序的内存空间,包括堆内存、栈内存、方法区...
本项目资源整体框架简单,清晰,适合初步学习使用。 基于QT的QOpenGLWidget类进行派生,对鼠标事件进行重载,使用OpenGL可编程渲染模式开发,涉及着色器程序的编写,并进行了相机、渲染器、物体类的抽象。还编写了...
Linux学习的初步文档是专为Linux初学者设计的教育资源,旨在帮助他们逐步了解并掌握这个开源操作系统的基础知识。Linux作为一款强大的服务器操作系统,其广泛应用在各种领域,包括云计算、网络服务、软件开发以及...
以下是对"FPGA初步学习"这一主题的详细解释。 一、FPGA的基础知识 1. FPGA结构:FPGA由可编程逻辑块(CLB)、输入/输出单元(IOB)、互连资源(如布线资源)等部分组成。这些基本单元通过配置存储器(SRAM)中的...