一、JVM的主要组成
1、类加载classLoader
1.1、类加载器是什么东西:
a、类加载器就是加载所有的类的工具,它加载的类在内存中只会存在一份,也就是生成的堆中的Class对象。不可以重复加载
b、在我们java编码里,一个类是用全限定名(包名加类名)标识的唯一的一个类,但在jvm里是根据类加载器+全限定名来标识,也就是说不同类加载器加载的同一个类,在内存中也是不同的Class
1.2、为什么会出现类加载:
1.3、类加载组成:
jvm的类加载classLoader包括三个:启动类加载器(bootClassLoader)、扩展类加载器(extClassLoader)和系统类加载器(applicationClassLoader);
启动类类加载:加载核心类的,底层c++实现的,jvm启动时候就去你jdk加载jre/lib/rt.jar下的class;查找范围:sun.mic.boot.class下面的路径
扩展类加载器:底层java实现的,设置父类加载器为启动类类加载器,ExtClassLoader
主要加载%JAVA_HOME%/jre/lib/ext
,此路径下的所有classes目录以及java.ext.dirs
系统变量指定的路径中类库;父类加载器为null(因为关系上父类加载器是启动类加载器,但是启动类加载器是c++,所以这里拟为null)。查找范围:java.ext.dirs下面的路径
系统类加载器:底层java实现的,设置父类加载器为扩展类类加载器,另外我们知道ClassLoader中有个getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。查找范围:java.class.path (也就是你的工程下的bin目录)下面的路径
java编写,加载程序所在的目录,如user.dir所在的位置的class;
注:MAVEN项目有一个.classPath文件标注class的文件存放位置,也可实现自己的类加载器;
1.4、怎么用:类加载执行的过程(双亲委托机制):
即一个类加载器接收到加载此类的请求时会先去请求父类加载器加载此类,如果父类还有父类则继续传给父类的父类,当找到最根的类加载器时(启动类加载器),加载器会尝试在自己的查找范围内找此类的class文件,若找到则加载,找不到就往回走,即告诉子类我不能处理这个任务,然后子类看看在他的范围能不能找到,找到就加载,再找不到继续往下传,都找不到报错
总之:有事往上级抛,上级都处理不了我再处理。上传的顺序为:自己的类加载器>系统类加载器>扩展类加载器>启动类加载器;下传的顺序:启动类加载器>扩展类加载器>系统类加载器>自己的类加载器;
1.5、类加载优缺点:
优点:避免类的重新加载,保证数据安全;确保类的唯一性(类的唯一性有全类名和类加载器决定);