jvm类加载器以及类加载原理学习

宏观运行java com.tuling.jvm.Math.class命令后执行的流程
底层C++调用sun.misc.launcher.getlauncher()方法,获取launcher对象,jvm全局唯一对象,同时会初始化好以下的类加载器,每个加载器的加载类的路径·是不一样的
1.引导类加载器(bootstapClassLoader)
c语言实现,加载jre的lib包的基础核心类库jar包
2.扩展类加载器(extClassLaoder)
java实现,加载jre的lib包下ext扩展目录jar包
3.应用类加载器(appClassLoader)
java实现,加载自己写的java字节码文件
3.自定义类加载器
在这里插入图片描述
所有类加载器都会调用到ClassLoader这个类的laodClass方法 因为引导类加载器bootstapClassLoader是顶级父加载器c语言编写 , 所以只有应用类加载器(appClassLoader)
getParent才会是null,应用类加载器(appClassLoader) 以及自己实现的的子类加载器 getParent才会有值,findLoadedClass会查询当前类加载器是否已经加载过准备加载的这个类
在这里插入图片描述

加载类的主要流程在classLoader.loadClass(“全类名”);

在这里插入图片描述
双亲委派机制:
在这里插入图片描述
为什么一定从AppClassLoader开始加载?
因为源码launcher.getClassLoader()方法返回就是appClassLoader
在这里插入图片描述
为什么使用双亲委派机制?
在这里插入图片描述
如果直接从上到下依次执行bootstapClassLoader→extClassLaoder→appClassLoader加载类
有人伪造java.lang.String类,那么bootstrapClassLoader会加载lib下的java.lang.String类,appClassLoader也会加载一次伪造的java.lang.String类 那么就会造成安全隐患
避免重复加载lib和ext中的类

自定义类加载器
自定义加载器通常应用场景:
1.加密:java代码很容易被反编译,如果你需要把自己的代码进行加密,可以先将编译后的代码用某种加密算法加密,然后实现自己的类加载器,负责将这段加密后的代码还原。

2.从非标准的来源加载代码:例如你的部分字节码是放在数据库中甚至是网络上的,就可以自己写个类加载器,从指定的来源加载类。

3.动态创建:为了性能等等可能的理由,根据实际情况动态创建代码并执行。

只需要继承java.lang.ClassLoader类即可,两个核心方法,loaderClass(String,boolean)已经实现双亲委派机制 findClass()方法 默认空实现,需要重写findCalss(String)方法 测试记得把C的字节码放在相应的目录下并且删除当前idea中的C.java 和C.class文件 由于自定义的类加载器的父加载器是AppClassLoader 否则由于双亲委派还是显示AppClassLoader加载的C类
为什么自定义类加载器的父加载器是AppClassLoader?
因为自定义类加载器继承自ClassLoader,所以先初始化ClassLoader父加载器,而ClassLoader中的private final ClassLoader parent;parent属性赋值由Launcher类中sun.misc.launcher.getlauncher()执行时赋值

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值