首页 > 技术文章 > JAVA类加载的过程及类加载器

li573925122 2018-03-13 15:42 原文

引言  

类对于一个JAVA程序员来说是在熟悉不过的东西了吧。因为JAVA作为一个纯面向对象的变成语言,我们编程的过程其实就是一个编造类和使用类的过程。但是对于类的加载过程以及JAVA中的类加载器多数人不是很清楚,因为国内的教程更多的是告诉你怎么做,而为什么却告知的比较少。今天查了些资料记下笔记,如有不正确的地方请多多包涵和指教。

首先看一下java虚拟机(JVM)中几个比较重要的区域:

方法区:存放已经加载的类信息,静态变量及代码块

堆区:存放类加载时生成的java.lang.class对象

栈区:由一个个栈帧组成,每个方法在运行时都有一个个方法栈组成,方法栈中保存有局部变量,方法出口等。没个方法的执行其实就是栈帧的压栈与出栈的过程。

常量池:方法区的一部分,主要放常量。

类加载的全过程

1、加载:类加载其实就是将静态class数据加载到方法区中形成可运行的动态数据。同时在堆中生成一个对应的java.lang.class对象作为方法区访问的入口。

2、链接:将JAVA类的二进制代码合并到JVM的运行状态之中的过程。
        验证:确保加载的数据符合JVM规范,没有安全方面的问题。
        准备:正式为类变量分配内存并初始值,内存在方法区中分配。
        解析:虚拟机常量池中的符号引用替换为直接引用。
3、初始化:执行类构造器clinit()方法的过程(将静态变量和静态语句块合并)虚拟保证一个类的client方法多线程下正确加锁和同步(是否需要初始化会根据其引用类型来定,只有主动引用才会引起类的初始化)
类的主动引用:new一个对象
                        调用静态(除final变量)
                           反射调用
                           虚拟机启动
 被动引用:数组定义
                   通过子类调用父类定义的静态域,子类不会初始化。
                   引用常量不会出发此类初始化
 

JAVA中类加载器结构(树状结构)

1:引导类加载器:加载JAVA核心包下的jar如:rt/下的jar包,内部使用原生代码实现

2:扩展类加载器:加载JAVA的扩展类库

3:应用类加载器:一般的应用程序都有他来加载

4:自定义加载器:用户可以自己定义类加载器

JAVA中的类加载是采用代理模式中的双亲委派机制实现的,即一个类首先会区尝试让父加载器进行加载。如果父加载器不能进行加载才通过自身加载器进行加载。这样做的好处是为了安全,因为这样做就可以有效避免我们定义与类库同名的JAVA类。因为即使你定义了,交给父类加载器来加载也是加载的系统内部的类库。

  

 

推荐阅读