`
rubyeye
  • 浏览: 27119 次
  • 性别: 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规范,希望能找到依据,内部实现机制还是很多不了解。

 

 

分享到:
评论

相关推荐

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

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

    decord:高效的视频加载器,可通过智能混洗进行深度学习,超级易消化

    Decord旨在处理尴尬的视频混洗体验,以便提供类似于随机图像加载器的流畅体验,以进行深度学习。 Decord还能够解码视频和音频文件中的音频。 可以将视频和音频切片在一起以获得同步结果。 因此,提供了视频和音频...

    学习笔记:有关网络知识的笔记

    textContent,innerText,outerText,textNode.data工程化JS JS Regenerator运行时同步网络包 webpack打包形成的模块结果分析样式加载器,css加载器,较少加载器,URL加载器样式文件,图片文字文件处理摇树初步组件...

    OFDM 系统中基于深度学习的信号检测:长短期记忆 (LSTM) 网络用于创建深度神经网络 (DNN),用于 OFDM 接收器处的符号分类。-matlab开发

    这是在深度学习工具箱中使用长短期记忆(LSTM)网络在接收器处实现符号分类以在OFDM系统中进行信号检测的示例。 基于 LSTM 的神经网络针对单个子载波进行训练,其中符号错误率 (SER) 被计算并与最小二乘 (LS) 和最小...

    backend:初步学习过程实践库

    Java编译型语言如C,C ++,代码是直接编译成机器代码执行,但是不同的平台(x86,ARM等)CPU的指令集不同,因此,需要编译类型语言如Python,Ruby没有这个问题,可以由解释器直接加载源码然后运行,代价是运行效率...

    俄罗斯方块游戏(学习测试版)

    //初步构思: //1.不用MFC //2.利用消息分析器 //3.设计Brick类:没有组合方块,都是一个方块作为一个对象处理。 类功能: 接口函数: 1.加载方块位图 2.在坐标(x,y)显示方块的不同类型 3.设定方块水平与垂直方向...

    颜色分类leetcode-wela:围绕Weka机器学习java库的Scala包装器

    这是目前非常初步的发展。 它只是我个人需要帮助从 Scala 代码执行预测的主要分类功能的包装器。 当前的代码已经尝试通过添加更多类型安全并使代码更直接地编写代码来简化 Weka 的使用。 由于它是 Weka 功能的轻量级...

    JAVA基础课程讲义

    静态初始化块(经常用来初始化类,加载类信息时执行!) 67 package 68 JDK中的主要包 68 import 68 eclipse的使用 69 继承(extend, inheritance) 70 为什么需要继承?继承的作用? 70 继承介绍 70 如何实现继承? ...

    java课程设计大作业-基于java构建的CrazyArcade泡泡堂游戏(源码+资源文件+说明文档)

    model.loader:包含资源加载器用于读取配置文件等信息,使用了单例设计模式 model.manager:包含元素管理器、工厂等,用于控制游戏各元素 model.vo:各种实体类,包括玩家、NPC、炸弹、方块等等 pro:配置文件目录,...

    Intro-to-Deep-Learning:此回购包含ipython笔记本,以向初学者进行初步介绍

    深度学习入门实验1包含三个笔记本。 每个笔记本的详细信息如下- Multilayer-Perceptron-Pytorch.ipynb:在此笔记本中,我们将看到如何实现一个简单的多层神经网络来对数字图像进行分类。 阅读完本笔记本后,您将能够...

    jfinal:jfinal原始码学习可以查看作者https

    开发过程中无需重启服务AOP支持,拦截器配置灵活,功能强大插件体系结构,扩展性强多视图支持,支持Enjoy,FreeMarker,JSP,Velocity强大的Validator初步验证功能功能齐全,拥有传统SSH框架的绝大部分核心功能

    like-vue:vue全家桶源码学习,将vue的计算,观看,组件插件化

    类与样式绑定 事件功能 组件功能 插槽 动态组件&初步组件 渲染函数 过滤器 指令 插件 混合蛋白 过渡&动画 为了更清晰地了解vue的各个功能,本项目将vue的各个功能最大化的抽离出来,设计为一个独立的插件。例如...

    asp.net知识库

    通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: State Server Gems 完整的动态加载/卸载程序集的解决方案 从NUnit中理解.NET自定义属性的应用(转载) 如何在.NET中实现脚本引擎 (CodeDom篇) .NET的插件...

    精通qt4编程(源代码)

    \20.2.3 加载翻译文件 476 \20.3 语言切换 477 \20.4 小结 477 \第21章 Qt单元测试框架 478 \21.1 QTestLib框架 478 \21.1.1 QTestLib 478 \21.1.2 第一个Qt单元测试 478 \21.2 数据驱动测试 480 \21.3 GUI测试 481 ...

    精通Qt4编程(第二版)源代码

    \20.2.3 加载翻译文件 476 \20.3 语言切换 477 \20.4 小结 477 \第21章 Qt单元测试框架 478 \21.1 QTestLib框架 478 \21.1.1 QTestLib 478 \21.1.2 第一个Qt单元测试 478 \21.2 数据驱动测试 480 \21.3 GUI...

    思库教育PHP零基础培训+进阶课程+PHP项目开发实战 21G PHP零基础学习视频教程.txt

    │ │ ├【思库教育】第一集 网页介绍,环境与编辑器.wmv │ │ └第四集 排版标签.wmv │ ├ │ │ ├LXE文件播放说明.txt │ │ ├ │ │ │ ├录像1.avi │ │ │ └录像2.avi │ │ ├ │ │ │ ├[思库教育]JS ...

    ASP.NET 3.5 开发大全word课件

    这是整部学习资料 由于太大第一章免费供应给大家 在我的上传资源中 如果觉得还不过希望大家给个好评 当然具体本书的作者就不深究了把! 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP...

    koa-island

    router LinValidator jsonwebtoken lodash知识点深度JS异常处理与初步异常初步异常链与局部异常处理深入Koa中间件合并范围应用理解Node.js在Web架构中的作用Koa2开发API requireDirectory自动路由加载LinValidator...

    领域驱动设计与模式实战

    2.1.1 为什么要学习模式 2.1.2 在模式方面要注意哪些事情 2.2 设计模式 2.3 架构模式 2.3.1 示例:层 2.3.2 另一个示例:领域模型模式 2.4 针对具体应用程序类型的设计模式 2.5 领域模式 2.6 小结 第3章 TDD与重构 ...

Global site tag (gtag.js) - Google Analytics