JVM内存溢出(二)之双亲委派机制

jvm加载类时时按需加载的,用到什么class文件时,采取加载类。

一、类加载器分类

站在java虚拟机的角度看,JVM支持两种加载器,分别为引导类加载器(BootstrapClassLoader)和自定义类加载器。从概念上来说自定义加载器一般是程序中由开发人员定义的一类加载器,然而java虚拟机规范中并没有这样定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义加载器。

一般来说在java8以及以前的版本都会用到如下三种加载器:

启动类加载器(Bootstrap Class Loader)
扩展类加载器(Extension Class Loader)
应用类加载器(Application Class Loader)


启动类加载器
该加载器使用C++实现(不会继承ClassLoader),是虚拟机自身的一部分。该类加载器主要是负责加载存放在JAVA_HOME\lib目录,或者被-Xbootclasspath参数指定路径存放的,并且是java虚拟机能识别的类库加载到虚拟机内存中。(eg:主要是加载java的核心类库,即加载lib目录下的所有class)

扩展类加载器
 这个类加载器主要是负责加载JAVA_HOME\lib\ext目录中,或者被java.ext.dirs系统变量所指定的路径中所有类库

应用类加载器
这个类的加载器是由sun.misc.Launcher$AppClassLoader来实现,因为该加载器是ClassLoader类中的getSystemClassLoader()方法的返回值,所以一般也称为该加载器为系统类加载器。该加载器主要是加载用户类路径上所有的类库,如果应用程序中没有定义过自己的类加载器,一般情况下这个就是程序的默认加载器。

二、类的加载流程和执行流程如下:

如果一个类加载器收到了类加载请求,它首先不会自动去尝试加载这个类,而是把这个类委托给父类加载器去完成,每一层依次这样,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成该加载请求时,这个时候子加载器才会尝试自己去加载,这个过程就是双亲委派机制。

JVM内存溢出(二)之双亲委派机制_第1张图片

三、双亲委派优缺点

3.1优点

避免类重复加载

保障核心api不被篡改

3.2缺点

类不能重复加载(tomcat打破双亲委派机制)

四、tomcat如何打破双亲委派机制

我们都知道可以用户tomcat同时部署多个war包。如果一个war包是spring4,另一个war包是spring5,加载同一个类,可能存在同一个类在不同版本下实现不同,tomcat是如何打破双亲委派的呢?

tomcat自定义了类加载器WebAppClassLoader,实现的类加载器WebAppClassLoade破了双亲委派机制

你可能感兴趣的:(jvm)