暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

秒懂类加载执行子系统

长夜难眠 2020-08-09
199

点击蓝字

关注不迷途


作用


通过查找具有特定名称的类或接口类型的二进制表示形式。并从该二进制表示形式创建类或接口。


然后获取类或接口并将其组合到Java虚拟机的运行时状态以便可以执行。


最后进行类或接口的初始化包括执行类或接口的初始化方法<clinit>。


过程


这个过程可分为三个阶段:加载、链接、初始化。


加载


加载是查找具有特定名称的类或接口类型的二进制表示形式并从该二进制表示形式创建类或接口的过程。


通过类全限定名获取获取定义此类的二进制字节流。


将字节流所代表的静态存储结构转化为方法区的运行时数据结构。


在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。


链接


链接是获取类或接口并将其组合到Java虚拟机的运行时状态以便可以执行的过程。


链接阶段包括验证、准备、解析。


验证


确保类或接口的二进制表示在结构上正确。


准备


准备工作包括为类或接口创建静态字段,并将这些字段初始化为其默认值。


静态字段的显式初始化程序是作为初始化而不是准备工作的一部分执行的。


解析


根据运行时常量池中的符号引用动态确定一个或多个具体值的过程。


初始化


初始化包括执行类或接口的初始化方法<clinit>,是同步的方法。


方法<clinit>由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,顺序是由语句在源文件中出现的顺序所决定的。


类加载器


引导类类加载器


Bootstrap ClassLoader,加载JAVA_HOME/lib路径下的核心类库,或者Xbootclasspath参数指定的路径下的jar包到内存中。


用户自定义类类加载器


ExtClassLoader,加载JAVA_HOME/lib/ext目录下或者由系统变量Djava.ext.dir指定位路径中的类库。


AppClassLoader加载用户自定义的类。


双亲委派模式


双亲委派模式要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。


请注意双亲委派模式中的父子关系并非通常所说的类继承关系,而是采用组合关系来复用父类加载器的相关代码。


用户自定义类加载器向上委派:CustomClassLoader >> AppClassLoader>>ExtClassLoader>>BootstrapClassLoader。


如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行。


如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。


如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式。


优势


为了防止重复加载同一个.class,请求加载类时先向上委托,如果父类加载器已经加载过了,就不用再加载了,保证数据安全


通过委托方式,防止恶意篡改jvm核心类库,哪怕篡改也不会加载,即使加载也不会是同一个Class对象了。


不同的加载器加载同一个class文件也不是同一个Class对象,这样保证了Class执行安全。



喜欢本篇内容点个在看吧


文章转载自长夜难眠,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论