jvm|JVM笔记二双亲委派机制( 二 )


双亲委派流程示意图
图二:双亲委派机制流程图
双亲委派机制的好处
JVM为什么要使用双亲委派这种机制呢?有什么好处呢?
通过我们自己写的java.lang.string这个类启动报错中 , 我们就可以得出以下双亲委派的优点:
1:保证了JVM提供的核心类不被篡改 , 保证class执行安全
比如上文的string类 , 无论哪个加载器要加载这个类的话 , 由于双亲委派机制 , 最终都会交由最顶层的启动类加载器来加载 , 这样保证了string类在各种类加载器环境中 , 都是同一个类 。 试想下 , 没有双亲委派机制的话 , 各个加载器自己加载string类 , 有可能不同类加载器加载的string方法不一样 , 那样的话 , 我们的程序是不是就会一片混乱了 。
2:防止重复加载同一个class
从图二:双亲委派机制流程图中 , 我们可以看出 , 委托向上问一问 , 如果加载过 , 就不用再加载了 。
双亲委派机制简单理解简单一句话:我爸是李刚 , 有事找我爸 。 简单三个字:往上捅
双亲委派就是 , 有啥事 , 先问问老爹 , 如果老爹不行 , 再问问爷爷 , 如果爷爷也没有 , 再告爸爸 , 爸爸再告诉诉儿子 , 你自己看着办吧 。
为什么要往上捅呢?是因为沙箱安全机制
四种类加载机制的管辖范围一:启动类加载器(Bootstrap ClassLoader):
是由c++编写的 , 是JVM自身的一部分 。 用来加载Java核心类库的(java.*)的 。 构造ExtClassLoader和AppClassLoader的 。
需要注意的是:由于其是虚拟机自身的一部分 , 开发者是服务直接获取到启动类加载器的引用的 , 所以是不允许直接通过引用进行操作 。
这个类加载器负责存放在<JAVA_HOME>\\lib目录中的 , 或是被-Xbootclasspath参数所指定的路径中的 , 并且是虚拟机识别的类库加载到虚拟机内存中
二:扩展类加载器(Extension ClassLoader):
Java语言编写的 , 加载扩展库 。 如classPath中的jrejavax.*(也即:<JAVA_HOME>\\lib\\ext目录中)或是java.ext.dir指定位置中的类 。 开发者可以直接使用这个扩展类加载器
Java语言编写的 , 这个加载器是由sun.misc.Launcher$ExtClassLoader来实现的
三:应用程序类加载器(Application ClassLoader)
这个类加载器是由sun.misc.Launcher#AppClassLoader实现的 。 由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值 。 所以也称为系统加载器 。
赋值加载用户类路径(ClassPath)上所指定的类库 。
四:用户自定义类加载器(CustomClassLoader)
【jvm|JVM笔记二双亲委派机制】Java语言编写的 , 用户自定义类加载器 , 可以加载指定路径的class文件