1.概述?

类加载器:负责.class文件加载到内存中,并为之生成对应的Class对象,也就是字节码对象。这样就可以使用这个类中的成员变量和方法了。而被加载到内存中的class文件就会变成class对象。

常见的类加载器有三种,每个加载器负责加载不同的位置的类:

  (1)Bootstrap:根类加载器

  (2)ExtClassLoader:扩展类加载器

  (3)AppClassLoader:系统、应用类加载器

关于上述加载器的区别:

说明:1、Bootstrap是最顶级的加载器。加载类文件不是我们自己书写的,是JRE/lib/rt.jar包下的。只有将这个包下面的所有类加载到内存中,才可以使用这个包下的所有类。

2.ExtClassLoader扩展类加载器,是用来加载JRE/lib/ext/*.jar这个包下的所有类,在这个jar包中,都是jdk内部自己使用的。

    3.AppClassLoader系统/应用类加载器。是用来加载ClassPath指定所有的jar或目录,classPath表示存放类路径。

2.委托机制

全盘负责委托机制:

ClassLoader(类加载器)加载类用的是全盘负责委托机制。

1)全盘负责:当一个ClassLoader(类加载器)加载一个类的时候,那么在这个类中所引用的所有其它的类通常也都由这个类加载器来加载。

举例:比如上述代码中我们在 ClassLoaderDemo1 类中书写如下代码:

public class ClassLoaderDemo1 {

public static void main(String[] args) {

// 获取当前类的加载器

ClassLoader loader = ClassLoaderDemo1.class.getClassLoader();

//输出当前类的类加载器

System.out.println(loader);//sun.misc.Launcher$AppClassLoader@b0014f0

//获取AppClassLoader类加载器的父类

ClassLoader parent = loader.getParent();

//输出AppClassLoader类加载器的父类加载器

System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@325e9e34

}

} 

说明:由于我们在ClassLoaderDemo1 类中使用了System类,那么System类也应该由ClassLoaderDemo1的类加载器加载到内存中。

换句话说,如果在A类中使用了B类,那么A类的加载器就会将B类也会加载到内存中,就是一个类的加载器同时把多个类都加载了。

2)委托机制:先让Parent(父)类加载器寻找,只有在Parent找不到的时候,才从自己的范围中寻找。

但是呢,全盘负责要和委托机制一起使用,一个类加载器在加载一个类的时候不是上来就先加载类,而是先咨询这个类加载器的父亲,先看他的父类加载器有没有要加载的类,如果已经存在要加载的类了,那么子类加载器就不会加载,因为在加载就会重复,产生冲突了,只有在父类加载器中找不到的时候,才从自己的范围中寻找。

举例:还是上述的代码,由于ClassLoaderDemo1 类是被 AppClassLoader 类加载器加载内存中的,那么根据全盘负责机制,AppClassLoader 类加载器也会将System类加载到内存中,但是在加载的时候,根据委托机制AppClassLoader 类加载器会先去咨询他的父亲ExtClassLoader 类加载器,而这个类加载器中也没有System类,那么又会去咨询ExtClassLoader 类加载器的父类Bootstrap类加载器,而在这个类加载器中是可以加载System类的,所以作为子类加载器AppClassLoader 就不会加载了,这样才能保证一个类只会被加载一次,任何一个类同时只会被加载一次。

如果一个类在父类加载器中找到了,那么就会把这个类加载之后保存到cache(缓存)中。

3)类加载器的cache(缓存)机制:如果cache中保存了这个类就直接返回它,如果没有才加载这个类,然后存入cache中,下一次如果有其他类在使用的时候就不会在加载了,直接去cache缓存拿即可。这就是为什么每个类只加载一次,内存只有一份的原因。

举例:还是上述代码中,当第一次使用System类的时候,那么System类就会被加载了,那么System类就会存储到内存中了,当下面代码中我们再一次使用System类的时候,由于内存中已经有了,那么就不会在去加载了,这时会直接拿过来用即可。

因此方法区中每一个类的字节码文件只有一份的原因由全盘负责、委托机制和类加载器的cache(缓存)机制共同决定。

Classloader机制的更多相关文章

  1. 【JVM】深度分析Java的ClassLoader机制(源码级别)

    原文:深度分析Java的ClassLoader机制(源码级别) 为了更好的理解类的加载机制,我们来深入研究一下ClassLoader和他的loadClass()方法. 源码分析 public abst ...

  2. 转 Java Classloader机制解析

    转 Java Classloader机制解析 发表于11个月前(2014-05-09 11:36)   阅读(693) | 评论(0) 9人收藏此文章, 我要收藏 赞1 慕课网,程序员升职加薪神器,点 ...

  3. tomcat的classloader机制

    本系列博客打算分析一下tomcat7.x的源码,其中可能会穿插一些java基础知识的介绍  读tomcat的源码的时候,我建议和官方的User Guide一起阅读,明白tomcat做某件事情的目的之后 ...

  4. Tomcat ClassLoader机制介绍

    本文旨在介绍JVM的类加载机制:同时分析Tomcat不能采用默认的加载机制的原因,并对其加载机制做了介绍. 1.JVM中的类加载机制 在Java2之后的版本中,类的加载采用的是一种称为双亲委派的代理模 ...

  5. ClassLoader 机制

    JAVA启动后,是经过JVM各级ClassLoader来加载各个类到内存.为了更加了解加载过程,我通过分析和写了一个简单的ClassLoader来粗浅的分析它的原理. JVM的ClassLoader分 ...

  6. 深度分析 Java 的 ClassLoader 机制(源码级别)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...

  7. 深度分析Java的ClassLoader机制(源码级别)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...

  8. 理解Java ClassLoader机制

    当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构: bootstrap classloader                |       extension cla ...

  9. 深度分析 Java 的 ClassLoader 机制(源码级别)(转)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...

  10. Java Classloader机制解析(转)

    做Java开发,对于ClassLoader的机制是必须要熟悉的基础知识,本文针对Java ClassLoader的机制做一个简要的总结.因为不同的JVM的实现不同,本文所描述的内容均只限于Hotspo ...

随机推荐

  1. python3----split and join

    s = "I am fine" s = s.split(" ") print(s) print("%".join(s)) results: ...

  2. 加载Chrome&Firefox配置

    一.加载Chrome配置 分析: Chrome加载配置的方法,只需要改下面一个地方,就是将username改成你本机电脑的名字(不要用中文) '--user-data-dir=C:\Users\use ...

  3. 正则表达式初识,re模块

    作业收藏 # 3.reversed和sorted和list列表类型内置的sort.reverse有什么区别? #reversed 的返回值是一个迭代器并不会直接修改原列表 sorted的返回值是生成一 ...

  4. Javadoc生成html帮助文档

    注意事项: 右键项目 -> Export -> Java -> JavaDoc -> 选定Public表示录入所有的源文件,其他的可想而知    按步骤走下去最后Finish时 ...

  5. android实现卸载提示

    这篇文章是整理的以前用过的一个功能,由于多种原因现在停用了,也希望这篇文章能帮助一些android入门的小童鞋.android是不提供监控卸载自己的功能的,这里使用了监控android日志的功能,an ...

  6. MySQL (时间)日期相减取天数

    select TO_DAYS(str_to_date('12/1/2001 12:00:00 AM','%m/%d/%Y')) -TO_DAYS(str_to_date('11/28/2001 12: ...

  7. Centos之常见目录作用介绍(九)

    我们先切换到系统根目录 / 看看根目录下有哪些目录 [root@localhost ~]# cd / [root@localhost /]# ls bin   dev  home  lib64  mn ...

  8. Testlink安装访问提示“应用程序DEFAULT WEB SITE”中的服务器错误

    错误摘要:HTTP错误403.14 - ForbiddenWeb服务器被配置为不列出此目录的内容.

  9. ORACLE中RECORD、VARRAY、TABLE的使用具体解释

     1     说明 1.1       RECORD 定义记录数据类型. 它类似于C语言中的结构数据类型(STRUCTURE).PL/SQL提供了将几个相关的.分离的.基本数据类型的变量组成一个总 ...

  10. SSH远程登陆docker容器

    环境: Ubuntu 16.04(mac osx的VMware Fushion环境) 任务: Ubuntu 16.04通过SSH登陆docker(目的是为了运行在其他服务器的Jenkins访问dock ...