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. hdu 3394(点双连通)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3394 思路:题目的意思是要求无向图中的冲突边和不需要边的条数,如果一个块中有多个环,则该块中的每条边都 ...

  2. C++11写算法之冒泡排序

    冒泡排序很形象,指从数组后面将更小的值慢慢浮到前面去,每遍历一趟使得最小值浮到最前面(指当前位置). 这里有点小技巧,当某一次遍历过程中发现无交换,则说明此时数组已经排序完成,可提前退出. 时间复杂度 ...

  3. Android OpenCV集成摄像头图片动态识别车牌号

    最近两天开发一个使用OpenCV集成的一个识别车牌号的项目,困难重重,总结一下相关经验,以及开发注意事项: 一.开发环境: Android Studio 个人版本 3.1.4 NDK下载:14b CM ...

  4. linux下不错的小软件

    1.Shutter截图软件 可以完成基本截图功能,而且还有图片编辑功能,可以涂鸦添加水印等. 以下的截图全部归功于shutter软件. 2.VLC media player 媒体播放器 3.Termi ...

  5. ADB简易安装方法

    ADB安装方法: 1. 下载ADB程序 下载地址: 链接:https://pan.baidu.com/s/1CfQL51pBz-2Wk_cYfJYXUw  提取码:bjp8 2. 配置环境变量 pat ...

  6. 巨蟒python全栈开发linux之centos6 第二篇

    1. .nginx负载均衡的实现 .准备三台机器,准备3台虚拟机,或者和俩同桌交流一下 192.168.226.128 是nginx资源服务器,返回页面的 192.168.226.129 用作ngin ...

  7. 数据库时间类型和 util 包下时间类型转换

    Java 中的类型 1. java.sql 包下给出三个数据库相关的日期时间类型,分别是 java.sql.Date, 表示日期,只有年月日,没有时分秒. java.sql.Time, 表示时间, 只 ...

  8. LinuxCentos系统安装Mariadb过程记录

    MariaDB数据库简介 MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可. 开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜 ...

  9. python多进程编程(一)

    multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.Pyt ...

  10. orange安装文档

    一.Orange简介    Orange是一个基于 OpenResty/Nginx 的 API Gateway,提供 API 及 “自定义规则” 的监控和管理,如访问统计.流量切分.AB 测试.API ...