我是靠谱客的博主 专一雪糕,最近开发中收集的这篇文章主要介绍类加载器 - class类加载过程、ClassLoder类加载器及ClassLoder双亲委托机制编程语言演变类加载大致流程 类加载到JVM流程结构图什么是类加载器类加载器源码解读 断点调试查看双亲委派原理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

编程语言演变

类加载大致流程 

类加载到JVM流程结构图

什么是类加载器

什么是双亲委派模型

类加载器加载的过程!

类加载过程 图说明! 

读取class文件来源那些

ClassLoader类加载器四种分类

类加载器触发条件

类加载器的双亲委派机制

双亲委派机制好处

如何打破双亲委派机制

类加载器源码解读

 断点调试查看双亲委派原理

1. 依次向上查找类加载器:

2. 依次向下查找加载需要new的对象


编程语言演变

类加载大致流程 

类加载到JVM流程结构图

加载Mayikt.class的整个流程及jvm结构图;

1. 线程共享的为颜色,线程私有的为颜色;

2. jdk1.8及之后版本方法区改名为元空间;

什么是类加载器

将我们class文件读取到内存中。

什么是双亲委派模型

双亲委派是JVM类加载机制,目的是确保JVM中使用类的一致性(换言之就是确保公共类都是JVM定义的类)。

双亲委派模型的过程是如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器完成。

类加载器加载的过程!

  类加载器加载我们的class文件,并且经历过验证、准备、解析,在初始化该类

类加载过程 图说明! 

读取class文件来源那些

  1.  自己写的java源代码 编译成class文件 硬盘读取
  2.  通过网络的方式下载class文件
  3.  War、Jar 解压之后都是class文件
  4.  从数据库中读取class文件
  5.  Java动态代理模式 反射/cglib 生成代理class

ClassLoader类加载器四种分类

  1. 启动类加载器 $JAVA_HOME/jre/lib下的文件;核心包:string.反射 代表rt.jar C语言;如果是启动类加载器读取的,获取classloader 是null 
  2. 扩展类加载器JAVA_HOME/jre/lib/ext目录中的文件 java写;
  3. 应用类加载器  读取我们当前项目中定义的引入jar包、写的class文件 java写;
  4. 自定义类加载器 读取class文件范围 都是属于自定义 java写的。(会打破双亲委派机制)

    类加载器

     注意:每个类加载器有自己不同的职责:读取class文件范围

类加载器触发条件

1.new 对象;

2.调用静态方法的时候;

3.main;

4.class.forname;

5.只要子类被加载的时候,父类也会被加载;

类加载器加载该类,不一定会初始化,

一个类一旦初始化的情况下,该类就一定被加载。

类加载器的双亲委派机制

首先在我们类加载器分为四种 自定义类加载器、应用类加载器、扩展类加载器、启动类加载器。

当一个类加载器收到请求之后,首先会依次向上查找到最顶层类加载器(启动类加载器),依次向下加载class文件,如果已经加载到class文件,子加载器不会加继续加载该class文件。

双亲委派机制好处

从下向上查找到最顶端的“启动类加载器”读取class文件,只要“启动类加载器”读取成功之后,以后不会再向下查找其它类加载器。

好处:目的就是为了防止开发者自定义的类与jdk定义源码类产生冲突问题,保证该类在内存中的唯一性。

           冲突的包名和类名,优先按照类加载器层级进行加载。

例如:用户自定义java.long.object包,类名叫做Object;这样会和jdk自带的Object重启,按理说启动项目应该会报错;

          但是事实启动项目是不会报错的,原理就是委托机制,首先从顶端类加载器找到了($JAVA_HOME/jre/lib目录下)jdk自带的Object类,就会加载近来,不会再往下找。

如何打破双亲委派机制

自定义类加载器,继承ClassLoader类,然后重写loadClass和findClass就可以了。

这样加载的类就不会向上找父类。

类加载器源码解读

Launcher 设定类加载器的依赖关系

 断点调试查看双亲委派原理

  每次new一个对象时,一定默认会走ClassLoader.getSystemClassLoader().loaderClass();方法,加载类到jvm中。

  断点调试new 一个对象的过程;

public class Test011 {
    public static void main(String[] args) {
1.        System.out.println(1);
2.        // ClassLoader.getSystemClassLoader().loadClass(); // loadClass()里边打上debug
3.        MayiktEntity mayiktEntity = new MayiktEntity(); // 打上debug
    }
}

注意:等debug走到第3行时,在去第2步的loadClass()中打上debug。  不然初始化加载的类比较多。

默认从底层app类加载器依次往上查找父类加载器, 

找到顶层父类加载器后依次往下去对应文件中加载需要new 的类。

默认情况下:当前线程关联的都是App应用加载器。

1. 依次向上查找类加载器:

递归,依次往上查找Ext、bootstrap类加载器:

2. 依次向下查找加载需要new的对象

类加载器的使用:https://blog.csdn.net/qq_36881887/article/details/111761115

最后

以上就是专一雪糕为你收集整理的类加载器 - class类加载过程、ClassLoder类加载器及ClassLoder双亲委托机制编程语言演变类加载大致流程 类加载到JVM流程结构图什么是类加载器类加载器源码解读 断点调试查看双亲委派原理的全部内容,希望文章能够帮你解决类加载器 - class类加载过程、ClassLoder类加载器及ClassLoder双亲委托机制编程语言演变类加载大致流程 类加载到JVM流程结构图什么是类加载器类加载器源码解读 断点调试查看双亲委派原理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部