类加载器子系统
来源:互联网 发布:淘宝店铺淘金币签到 编辑:程序博客网 时间:2024/05/29 06:42
类加载器子系统(Class Loader)
类加载器子系统负责加载编译好的.class字节码文件,并装入内存,使JVM可以实例化或以其它方式使用加载后的类。JVM的类加载子系统支持在运行时的动态加载,动态加载的优点有很多,例如可以节省内存空间、灵活地从网络上加载类,动态加载的另一好处是可以通过命名空间的分隔来实现类的隔离,增强了整个系统的安全性。
1、ClassLoader的分类:
a.启动类加载器(BootStrap Class Loader):负责加载rt.jar文件中所有的Java类,即Java的核心类都是由该ClassLoader加载。在Sun JDK中,这个类加载器是由C++实现的,并且在Java语言中无法获得它的引用。
b.扩展类加载器(Extension Class Loader):负责加载一些扩展功能的jar包。
c.系统类加载器(System Class Loader):负责加载启动参数中指定的Classpath中的jar包及目录,通常我们自己写的Java类也是由该ClassLoader加载。在Sun JDK中,系统类加载器的名字叫AppClassLoader。
d.用户自定义类加载器(User Defined Class Loader):由用户自定义类的加载规则,可以手动控制加载过程中的步骤。
2、ClassLoader的工作原理
类加载分为装载、链接、初始化三步。
a.装载
通过类的全限定名和ClassLoader加载类,主要是将指定的.class文件加载至JVM。当类被加载以后,在JVM内部就以“类的全限定名+ClassLoader实例ID”来标明类。
在内存中,ClassLoader实例和类的实例都位于堆中,它们的类信息都位于方法区。
装载过程采用了一种被称为“双亲委派模型(Parent Delegation Model)”的方式,当一个ClassLoader要加载类时,它会先请求它的双亲ClassLoader(其实这里只有两个ClassLoader,所以称为父ClassLoader可能更容易理解)加载类,而它的双亲ClassLoader会继续把加载请求提交再上一级的ClassLoader,直到启动类加载器。只有其双亲ClassLoader无法加载指定的类时,它才会自己加载类。
双亲委派模型是JVM的第一道安全防线,它保证了类的安全加载,这里同时依赖了类加载器隔离的原理:不同类加载器加载的类之间是无法直接交互的,即使是同一个类,被不同的ClassLoader加载,它们也无法感知到彼此的存在。这样即使有恶意的类冒充自己在核心包(例如java.lang)下,由于它无法被启动类加载器加载,也造成不了危害。
由此也可见,如果用户自定义了类加载器,那就必须自己保障类加载过程中的安全。
b.链接
链接的任务是把二进制的类型信息合并到JVM运行时状态中去。
链接分为以下三步:
a.验证:校验.class文件的正确性,确保该文件是符合规范定义的,并且适合当前JVM使用。
b.准备:为类分配内存,同时初始化类中的静态变量赋值为默认值。
c.解析(可选):主要是把类的常量池中的符号引用解析为直接引用,这一步可以在用到相应的引用时再解析。
c.初始化
初始化类中的静态变量,并执行类中的static代码、构造函数。
JVM规范严格定义了何时需要对类进行初始化:
a、通过new关键字、反射、clone、反序列化机制实例化对象时。
b、调用类的静态方法时。
c、使用类的静态字段或对其赋值时。
d、通过反射调用类的方法时。
e、初始化该类的子类时(初始化子类前其父类必须已经被初始化)。
f、JVM启动时被标记为启动类的类(简单理解为具有main方法的类)。
3、自定义类加载器和打破双亲委派
一般的场景中使用Java默认的类加载器即可,但有时为了达到某种目的又不得不实现自己的类加载器,例如为了达到类库的互相隔离,例如为了达到热部署重加载功能
a、沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可。如下例子:
①先定义一个待加载的类Test,它很简单,只是在构建函数中输出由哪个类加载器加载。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
②定义一个TestClassLoader类继承ClassLoader,重写findClass方法,此方法要做的事情是读取Test.class字节流并传入父类的defineClass方法即可。然后就可以通过自定义累加载器TestClassLoader对Test.class进行加载,完成加载后会输出“TestLoader”。
b、打破双亲委派机制则不仅要继承ClassLoader类,还要重写loadClass和findClass方法,如下例子:
①定义Test类。
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
②重新定义一个继承ClassLoader的TestClassLoaderN类,这个类与前面的TestClassLoader类很相似,但它除了重写findClass方法外还重写了loadClass方法,默认的loadClass方法是实现了双亲委派机制的逻辑,即会先让父类加载器加载,当无法加载时才由自己加载。这里为了破坏双亲委派机制必须重写loadClass方法,即这里先尝试交由System类加载器加载,加载失败才会由自己加载。它并没有优先交给父类加载器,这就打破了双亲委派机制。
- 类加载器子系统
- 类加载执行子系统
- 类加载器子系统的类加载机制(双亲委派机制)
- 初步了解 Java类加载子系统
- JVM类加载及执行子系统
- 深入理解Java虚拟机 类加载子系统1
- 深入理解Java虚拟机 类加载子系统2
- 类加载及执行子系统的案例与实战
- 类加载及执行子系统的案例与实践
- 类加载及执行子系统的案例与实战
- 子系统类加载分析情况(中间件是weblogic)
- java虚拟机学习笔记二:浅谈虚拟机的类加载执行子系统机制
- 深入理解Java虚拟机----(八)类加载和执行子系统的应用
- JVM笔记整理(第9章 类加载及执行子系统的案例与实战)
- 第9章 类加载及执行子系统的案例与实战
- 《深入理解Java虚拟机》读书笔记5——类加载及执行子系统的案例与实战
- [深入理解Java虚拟机]第九章 字节码执行引擎-类加载及执行子系统的案例与实战
- 加载、类加载、类加载器
- linux下安装jdk1.8
- 常用的日期格式化转换符
- pip安装的时候报错
- Linux android下常用命令
- HDU
- 类加载器子系统
- Spring mvc(3)如何获取所有的requestMapping
- TIME_WAIT状态
- Spring Boot (教程七: servlet)
- LeetCode 16. 3Sum Closest
- java学习第一天
- MyBatis 持久层框架
- 前台向后台传递参数时,特殊字符(+、-)丢失的问题
- tensorflow安装(windows,linux均可)