`
rubyeye
  • 浏览: 27398 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

类加载器初步学习

阅读更多

    近期学习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

    学习JDBC第一个练习,封装JDBC的源代码,初步封装,通过反射Class实例,类文件加载阶段执行,而且只执行一次的作封装,如:获取类加载器,然后通过类加载器获取输入数据流对象,创建Properties实例对象,加载配置项文件,将...

    matlab神经网络和优化算法:1感知器神经网络初步学习程序.zip

    这个压缩包“matlab神经网络和优化算法:1感知器神经网络初步学习程序.zip”显然包含了一个关于感知器网络的初学者教程。 感知器神经网络,最初由Frank Rosenblatt在1957年提出,是一种最简单的前馈神经网络,由...

    入门MATLAB神经网络和优化算法专题:1 感知器神经网络初步学习程序.zip

    在这个"入门MATLAB神经网络和优化算法专题:1 感知器神经网络初步学习程序"的压缩包中,我们将会探讨感知器神经网络的基础知识以及如何在MATLAB中实现它。 感知器是神经网络的最简单形式,由Frank Rosenblatt于1957...

    深度学习框架pytorch初步学习代码

    在进行深度学习模型构建时,我们通常会用到`nn.Module`,它是PyTorch中的神经网络模块类。你可以通过定义`__init__`和`forward`方法来创建自定义的网络结构。在`__init__`中初始化网络层,如卷积层(`nn.Conv2d`)、...

    初步学习jQuery的概念及选择器

    初步学习jQuery的概念及选择器 jQuery是一个功能强大且流行的JavaScript库,它提供了许多实用的方法来简化网站开发和交互设计。 本文将对jQuery的基本概念和选择器进行介绍,旨在帮助读者快速掌握jQuery的基础知识...

    opencv识别-初步学习

    `cv2.CascadeClassifier`类可以加载预训练的级联分类器XML文件进行物体检测。 6. **图像变换**:包括几何变换(如缩放、旋转、仿射变换)和光照变换(如直方图均衡化)。`cv2.warpAffine()`和`cv2.equalizeHist()`...

    新人学习autoware代码初步指导.docx

    ### 新人学习Autoware代码初步指导 #### 一、Autoware.AI简介与系统架构 Autoware.AI是一款革命性的"All-in-One"开源自动驾驶软件,它在全球范围内首次实现了自动驾驶技术的全面开源化。该软件运行于ROS1操作系统...

    Android高级应用源码-图片加载器.zip

    "Android高级应用源码-图片加载器.zip"提供的就是一个针对这一需求的解决方案。这个压缩包包含了Android图片加载器的源代码,可以帮助开发者深入理解图片加载的机制,并为自己的项目提供参考。 首先,我们要了解...

    QT quick初步学习.docx

    QT Quick 的初步学习主要包括以下几个方面: 1. **QML 基础**: - QML 提供了一种简洁的方式来定义 UI 元素,如按钮、文本框等,通过 JSON 样式的语法来创建和配置对象。 - QML 文件通常以 `.qml` 结尾,可以包含...

    matlab神经网络和优化算法:1 感知器神经网络初步学习程序.zip

    在本压缩包“matlab神经网络和优化算法:1 感知器神经网络初步学习程序.zip”中,我们主要探讨的是使用MATLAB环境下的神经网络模型,特别是感知器神经网络的基础知识及其应用。MATLAB作为一款强大的数学计算软件,为...

    jquery初步入门学习小资料

    **jQuery 初步入门学习小资料** jQuery 是一个广受欢迎的 JavaScript 库,它极大地简化了 JavaScript 的使用,使得开发者可以高效地实现网页交互、动画效果以及与服务器的数据通信。这个压缩包文件提供了关于 ...

    Java虚拟机(1)

    ClassLoader的层次结构包括Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和App ClassLoader(应用程序类加载器),它们共同负责加载不同级别的类。开发者还可以自定义类加载器,以...

    opencv初步学习总结.docx

    8. 机器学习与深度学习:OpenCV集成了传统的机器学习库(如SVM、决策树等)以及深度学习框架(如DNN模块,支持TensorFlow、Caffe等模型的加载和推理)。 在实际项目中,OpenCV可以通过Python、Java、C++等多种编程...

    JAVA工程师实习一周总结【推荐下载】.doc

    这一周的实习让我对JAVA开发有了更深入的理解,特别是对Java虚拟机(JVM)和类加载器(ClassLoader)机制有了初步的认识。 Java虚拟机是Java语言运行的基础,它负责管理程序的内存空间,包括堆内存、栈内存、方法区...

    基于QT使用OpenGL,加载obj模型,进行鼠标交互

    本项目资源整体框架简单,清晰,适合初步学习使用。 基于QT的QOpenGLWidget类进行派生,对鼠标事件进行重载,使用OpenGL可编程渲染模式开发,涉及着色器程序的编写,并进行了相机、渲染器、物体类的抽象。还编写了...

    linux学习的初步文档

    Linux学习的初步文档是专为Linux初学者设计的教育资源,旨在帮助他们逐步了解并掌握这个开源操作系统的基础知识。Linux作为一款强大的服务器操作系统,其广泛应用在各种领域,包括云计算、网络服务、软件开发以及...

    FPGA初步学习

    以下是对"FPGA初步学习"这一主题的详细解释。 一、FPGA的基础知识 1. FPGA结构:FPGA由可编程逻辑块(CLB)、输入/输出单元(IOB)、互连资源(如布线资源)等部分组成。这些基本单元通过配置存储器(SRAM)中的...

Global site tag (gtag.js) - Google Analytics