JVM面试宝典-类加载器

说下JVM中类加载器分类与核心功能
Java里有如下几种类加载器
引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等
扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包
应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类
自定义加载器:负责加载用户自定义路径下的类包
看一个 类加载器 示例:
 public class TestJDKClassLoader {
2
3 public static void main(String[] args) {
4 System.out.println(String.class.getClassLoader());
5 System.out.println(com.sun.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName());
6 System.out.println(TestJDKClassLoader.class.getClassLoader().getClass().getName());
7
8 System.out.println();
9 ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
10 ClassLoader extClassloader = appClassLoader.getParent();
11 ClassLoader bootstrapLoader = extClassloader.getParent();
12 System.out.println("the bootstrapLoader : " + bootstrapLoader);
13 System.out.println("the extClassloader : " + extClassloader);
14 System.out.println("the appClassLoader : " + appClassLoader);
15
16 System.out.println();
17 System.out.println("bootstrapLoader加载以下文件:");
18 URL[] urls = Launcher.getBootstrapClassPath().getURLs();
19 for (int i = 0; i < urls.length; i++) {
20 System.out.println(urls[i]);
21 }
22
23 System.out.println();
24 System.out.println("extClassloader加载以下文件:");
25 System.out.println(System.getProperty("java.ext.dirs"));
26
27 System.out.println();
28 System.out.println("appClassLoader加载以下文件:");
29 System.out.println(System.getProperty("java.class.path"));
30
31 }
32 }
33
34 运行结果:
35 null
36 sun.misc.Launcher$ExtClassLoader
37 sun.misc.Launcher$AppClassLoader
38
39 the bootstrapLoader : null
40 the extClassloader : sun.misc.Launcher$ExtClassLoader@3764951d
41 the appClassLoader : sun.misc.Launcher$AppClassLoader@14dad5dc
42
43 bootstrapLoader加载以下文件:
44 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/resources.jar
45 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/rt.jar
46 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/sunrsasign.jar
47 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/jsse.jar
48 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/jce.jar
49 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/charsets.jar
50 file:/D:/dev/Java/jdk1.8.0_45/jre/lib/jfr.jar
51 file:/D:/dev/Java/jdk1.8.0_45/jre/classes
52
53 extClassloader加载以下文件:
54 D:\dev\Java\jdk1.8.0_45\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
55
56 appClassLoader加载以下文件:
57 D:\dev\Java\jdk1.8.0_45\jre\lib\charsets.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\deploy.jar;D:\dev\Java\jdk1.8.0_45\jre
\lib\ext\access‐bridge‐64.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\cldrdata.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\dns
ns.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\jaccess.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\jfxrt.jar;D:\dev\Java\jdk1.8.
0_45\jre\lib\ext\localedata.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\nashorn.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\su
nec.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\sunjce_provider.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\sunmscapi.jar;D:\d
ev\Java\jdk1.8.0_45\jre\lib\ext\sunpkcs11.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\ext\zipfs.jar;D:\dev\Java\jdk1.8.0_45\jr
e\lib\javaws.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\jce.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\jfr.jar;D:\dev\Java\jdk1.8.0_
45\jre\lib\jfxswt.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\jsse.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\management‐
agent.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\plugin.jar;D:\dev\Java\jdk1.8.0_45\jre\lib\resources.jar;D:\dev\Java\jdk1.8.
0_45\jre\lib\rt.jar;D:\ideaProjects\project‐all\target\classes;C:\Users\zhuge\.m2\repository\org\apache\zookeeper\zook
eeper\3.4.12\zookeeper‐3.4.12.jar;C:\Users\zhuge\.m2\repository\org\slf4j\slf4j‐api\1.7.25\slf4j‐api‐1.7.25.jar;C:\Use
rs\zhuge\.m2\repository\org\slf4j\slf4j‐log4j12\1.7.25\slf4j‐log4j12‐1.7.25.jar;C:\Users\zhuge\.m2\repository\log4j\lo
g4j\1.2.17\log4j‐1.2.17.jar;C:\Users\zhuge\.m2\repository\jline\jline\0.9.94\jline‐0.9.94.jar;C:\Users\zhuge\.m2\repos
itory\org\apache\yetus\audience‐annotations\0.5.0\audience‐annotations‐0.5.0.jar;C:\Users\zhuge\.m2\repository\io\nett
y\netty\3.10.6.Final\netty‐3.10.6.Final.jar;C:\Users\zhuge\.m2\repository\com\google\guava\guava\22.0\guava‐
22.0.jar;C:\Users\zhuge\.m2\repository\com\google\code\findbugs\jsr305\1.3.9\jsr305‐1.3.9.jar;C:\Users\zhuge\.m2\repos
itory\com\google\errorprone\error_prone_annotations\2.0.18\error_prone_annotations‐2.0.18.jar;C:\Users\zhuge\.m2\repos
itory\com\google\j2objc\j2objc‐annotations\1.1\j2objc‐annotations‐1.1.jar;C:\Users\zhuge\.m2\repository\org\codehaus\m
ojo\animal‐sniffer‐annotations\1.14\animal‐sniffer‐annotations‐1.14.jar;D:\dev\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar
类加载双亲委派机制是怎么回事
双亲委派机制说简单点就是,先找父亲加载加载,不行再由儿子加载器自己加载
比如我们自己写的一个类,最先会找应用程序类加载器加载,应用程序类加载器会先委托扩展类加载器加载,扩展类加载器再委托引导类
加载器,顶层引导类加载器在自己的类加载路径里找了半天没找到你自己写的类,则向下退回加载类的请求,扩展类加载器收到回复就自
己加载,在自己的类加载路径里找了半天也没找到,又向下退回类的加载请求给应用程序类加载器,应用程序类加载器于是在自己的类加
载路径里找你自己写的类,结果找到了就自己加载了。
为什么会有双亲委派机制?
沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证 被加载类的唯一性
Tomcat底层类加载是用的双亲委派机制吗
不是!Tomcat底层类加载打破了双亲委派机制!
一个Tomcat Web容器可能需要部署两个应用程序,不同的应用程序可能会 依赖同一个第三方类库的不同版本 ,不能要求同一个类库在同
一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。 
Tomcat自定义加载器
tomcat的几个主要类加载器:
commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;
catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见,比如加载war包里相关的
tomcat 这种类加载机制违背了java 推荐的双亲委派模型了吗?答案是:违背了。 
很显然,tomcat 不是这样实现,tomcat 为了实现隔离性,没有遵守这个约定, 每个webappClassLoader加载自己的目录下的class文
件,不会传递给父类加载器,打破了双亲委派机制
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值