资讯专栏INFORMATION COLUMN

浅谈java classloader

liuyix / 435人阅读

摘要:类加载器三杰有三类,分别是以及。线程上下文类加载器线程上下文类加载器可以不遵循双亲委派机制。免费领取验证码内容安全短信发送直播点播体验包及云服务器等套餐更多网易技术产品运营经验分享请访问网易云社区。文章来源网易云社区

本文由作者张远道授权网易云社区发布。

类加载器三杰

jvm有三类classloader,分别是bootstrap classloader,extended classloader以及system classloader。

bootstrap classloader是系统在启动jvm时默认加载的。当用户在命令行输入java Test时,系统会首先加载jvm。在windows系统下,jvm的路径通常位于%JAVA_HOME%/jdk/jre/client/jvm.dll和%JAVA_HOME%/jdk/jre/server/jvm.dll.

bootstrap classloader加载后,会载入extended classloader,并将extended classloader的父类设为bootstrap classloader。然后,bootstrap classloader接着载入system classloader,并将system classloader的父类设为extended classloader。至此,bootstrap--extended--system三级继承结构形成。

bootstrap classloader在jvm启动之后自动加载。bootstrap classloader由c实现,不属于java类。

extended classloader由java实现,通常为sun.misc.Lancher$ExtClassLoader.

system classloader由java实现,通常为sun.misc.Lancher$AppClassLoader.

其中,

bootstrap classloader负责加载sun.boot.class.path路径下的.class文件以及jar包。

extended classloader负责加载java.ext.dirs路径下的.class文件以及jar包。

system classloader负责加载java.class.path路径下的.class文件以及jar包。

sun.boot.class.path通常对应环境变量CLASSPATH的路径。

java.ext.dirs通常对应JAVA_HOME/jre/lib/ext目录。

java.class.path对应用户自身的类路径。

类加载到何处

据可靠情报,jvm由方法区,堆,栈,pc寄存器和本地方法栈构成。类加载器的任务就是将class二进制文件加载到方法区,供虚拟机模制出在堆中存放的对象。

双亲委托机制

classloader加载类的过程为:

检查被加载类是否被加载。

如果没有被加载则调用父classloader加载该类。

如果1、2不成功,则仍由自身进行类加载。

这种机制又叫双亲委派机制。

双亲委派机制的好处是,避免多个类加载器加载同一个类的不同拷贝到内存(jvm的方法区)中。因为如果类A由ClassLoaderA加载,同时,又被ClassLoaderB加载,这样,内存中就会存在两份不同的A的定义,于是形成A既是ClassLoaderA罩的,又是ClassLoaderB罩着,造成灾难性后果。

用户自定义类的加载顺序通常为:

首先调用AppClassLoader加载类,AppClassLoader调用ExtClassLoader,ExtClassLoader调用BootClassLoader,BootClassLoader在sun.boot.class.path寻找改类,没找到,加载失败;ExtClassLoader也未加载类,失败,最后由AppClassLoader加载成功。从这个加载顺序可以看出来,三个类加载器的对类的可见性是不同的。

java中的类是由java的全名以及类的classloader来限定的。只有当二者完全一样才会认为是同一个类。否则是不同的类。因此,可以定义一个同名的类,包名也一样,只要保证该类被不同的类加载器加载即可。

当前类加载器和线程上下文类加载器

当前类加载器

当前类加载器是指当前方法所在的类使用的类加载器。在程序中使用Class.forName或者Class.getResource抑或Class.class时就是使用的该类加载器。

线程上下文类加载器

线程上下文类加载器可以不遵循双亲委派机制。线程的上下文类加载器有Thread.currentThread().setContextClassLoader()来为当前线程设置线程上下文类加载器。如果没有设置当前线程的上下文类加载器,则继承父类的上下文类加载器。

为什么还需要线程上下文类加载器?

考虑一种情况,当我们的程序必须由jvm的核心代码去加载第三方类的时候。比如jndi,jndi的核心是rt.jar包中实现的,由Bootstrap classloader负责加载,但是jndi必须加载第三方厂商的具体的jndi实现,这个时候调用Bootstrap加载只对其子类加载器可见的类,就会出现失败。这个时候就可以使用线程上下文类加载器。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区。

文章来源: 网易云社区

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25357.html

相关文章

  • 【效率专精系列】几种常见的JVM热部署技术及实现难点浅谈

    摘要:而热部署技术能够帮助开发人员减少重新部署的等待时间。本文的目的为调研热部署的技术现状及其对开发效率的帮助,并简单梳理其技术实现的难点。热部署技术总结热部署目前有多种技术实现官方开源商业。 开发、自测、联调期间代码可能会被频繁地修改,通常即使只增加了一行代码,都需要重启容器以检查执行效果。而热部署技术能够帮助开发人员减少重新部署的等待时间。本文的目的为调研热部署的技术现状及其对开发效率的...

    dongfangyiyu 评论0 收藏0
  • Java的一些题目

    摘要:需要注意的是对于方法或者代码块,当出现异常时,会自动释放当前线程占用的锁,因此不会由于异常导致出现死锁现象。用于实现线程间的通信,它是为了解决难以使用的问题。 速度StringBuilder>StringBuffer>String,StringBuffer线程安全 线程安全的集合有:Vector、Stack、HashTable、ConcurrentHashMap、 CopyOnWr...

    jokester 评论0 收藏0
  • Java学习】JDBC的学习(了解CLass等)

    摘要:同时也有一些儿高级的处理,比如批处理更新事务隔离和可滚动结果集等。连接对象表示通信上下文,即,与数据库中的所有的通信是通过此唯一的连接对象。因为是针对类的关系而言,所以一个对象对应多个类的实例化。返回表示查询返回表示其它操作。 JDBC是什么? JDBC是一个Java API,用中文可以通俗的解释为,使用Java语言访问访问数据库的一套接口集合。这是调用者(程序员)和实行者(数据库厂商...

    cjie 评论0 收藏0
  • 详细深入分析 Java ClassLoader 工作机制

    摘要:作用负责将加载到中审查每个类由谁加载父优先的等级加载机制将字节码重新解析成统一要求的对象格式类结构分析为了更好的理解类的加载机制,我们来深入研究一下和他的方法。就算两个是同一份字节码,如果被两个不同的实例所加载,也会认为它们是两个不同。 申明:本文首发于 详细深入分析 ClassLoader 工作机制 ,如有转载,注明原出处即可,谢谢配合。 什么是 ClassLoader ? 大家...

    mdluo 评论0 收藏0
  • 猫头鹰的深夜翻译:理解javaclassloader

    摘要:它们是通过来自远程的服务器的连接发送字节码并在本地运行,这一点令人兴奋。中有一个自定义的,它不是从本地文件系统加载类文件,而是从远程服务器上获取,通过加载原始字节码,再在中转化为类。它将字节码解析为运行时的数据结构,检查其有效性等。 前言 Java ClassLoader是java运行系统中一个至关重要但是经常被忽略的组件。它负责在运行时寻找并加载类文件。创建自定义的ClassLoad...

    Eminjannn 评论0 收藏0

发表评论

0条评论

liuyix

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<