类加载器分为四种

启动类加载器:C/C++写的,其他加载器都是java写的。具体不属于一个java类,在JVM中,加载JVM需要的基本类, %JAVA_HOME%/jre/lib 下的。
扩展类加载器:加载java扩展的基本类, %JAVA_HOME%/jre/lib/ext 下的。
系统类加载器/应用类:用来加载classpath(类路径)下的class文件
自定义类加载器:用来加载自定义内容.此加载器需要用户自己继承Classloader

双亲委派模型

image.png
上图这种层层递进的关系就是双亲委派模型,他要求除了启动类加载器,其他的加载器必须要有自己的父类加载器。即优先父类加载器加载!
当一个类需要被加载的时候,不会自己马上去加载这个类,而是向上询问/委派。本质上就是 loadClass 函数的递归调用。
从自定义加载器开始,一直向上问有没有加载器已经加载,或者在自己的范围内可以加载,直到最上层的启动类加载器。启动类加载器再向下委派,告知自己无法加载,再由子类去加载。

优势:

1、这样可以保护JAVA的核心类库,比如自己创建一个新的String类,但是在JAVA核心类中有String类,此时就不会去加载这个自定义的String类。
2、防止类的重复加载,向上委派的过程也就可以查看父类中是否已经加载过了

怎么打破?

已知是通过loadClass函数递归调用,那么可以重写该方法去打破默认的双亲委派模型
包括其他几种:

  • loadClass() 就是主要进行类加载的方法,默认的双亲委派机制就实现在这个方法中
  • findClass() 根据名称或位置加载.class字节码
  • definclass() 把字节码转化为Class

    Tomcat打破双亲委派模型

    image.png
    原因:
    为了让每一个webapp都隔离,打破了该模型
    与jvm一样,使用自己的classload加载自己的类,实现安全性。
    具体
    CommenClassLoad:Tomcat基本类加载器
    CatalinaClassLoad:私有加载器,web不可见
    SharedClassLoad:各个Wedapp共享的类加载器,web和加载路劲类可见
    WebappClassLoad:各个webapp私有类加载器,每个web的仅自己可见

    JDBC打破双亲委派模型

    1、通过,去调用应用层类加载器(自定义类加载器),加载了jdbc里jar包下的MATA/INFO里的services中的Driver
    2、通过上下文类加载器去加载Driver ,打破了双亲委派
    原生的JDBC中的类是放在rt.jar包的,是由启动类加载器进行类加载的,在JDBC中的Driver类中需要动态去加载不同数据库类型的Driver类,而mysql-connector-.jar中的Driver类是用户自己写的代码,那启动类加载器肯定是不能进行加载的,既然是自己编写的代码,那就需要由应用程序启动类去进行类加载。于是乎,这个时候就引入线程上下文件类加载器(Thread Context ClassLoader)。有了这个东西之后,程序就可以把原本需要由启动类加载器进行加载的类,由应用程序类加载器去进行加载了。下面看看JDBC中是怎么去应用的呢
    链接:https://www.jianshu.com/p/60dbd8009c64

    突然出现频繁FullGC怎么排查?

泛型是什么?解决什么问题?什么情况用?