理解jvm —— 类加载机制

一、类的生命周期

1.加载 —— 读取二进制内容。

2.验证 —— 验证class文件格式规范、语义分析、引用验证、字节码验证。

3.准备 —— 分配内存、设置类static修饰的变量初始值。

4.解析 —— 类、接口、字段、类方法等解析。

5.初始化 —— 为静态变量赋值;执行静态代码块。

6.使用 —— 创建实例对象。

7.卸载 —— 在jvm方法区中进行卸载。

二、类加载器

1作用:类加载器负责装入类、搜索网络、jar、zip、文件夹、二进制数据、内存等指定位置的类资源。一个java程序运行,至少需要有三个类加载器实例,负责不同的加载。

2.分类

    核心类库加载器(Bootstrap loader):使用C++实现的,没有对应的java对象,因此在java中只能用null来指代,核心类库加载器主要负责加载最为基础,最为重要的类,比如存放在JRE的lib目录下的jar包中的类(以及由虚拟机参数-Xbootclasspath指定的类)。

    扩展类加载器(extension class loader):父类是核心类库加载器,它主要负责相对次要,但通用的类,比如JRE的lib/ext目录下的jar包中的类(以及由系统变量java.ext.dirs指定的类)

    应用类加载器(application class loader):父类是扩展类加载器,它负责加载应用程序路径下的类(主要包括:虚拟机参数-cp/-classpath、系统变量java.class.path或环境变量CLASSPATH所指定的路径)。默认情况下,应用程序中的类,都是由应用类加载器完成加载的。

    自定义类加载器:用于自定义加载方式;举例来说,我们可以对class文件进行加密,加载时在利用自定义的类加载器对其解密。

3.查看类对应的加载器:通过JDK-API进行查看——java.lang.Class.getClassLoader(),这个返回装载类的类加载器,如果这个类是由bootstrapClassLoader加载的,那么这个方法就会返回null。

4.jvm去哪里加载类:在AppClassLoader的源码中,有指定的配置项java.class.path,指定去那些地址加载类资源;并且可以在程序运行时,使用jcmd + 进程号 + VM.system_properties

三、双亲委派模式

1.如何保证类的唯一性:类在jvm的唯一性是由类加载器 + 类名来表示,也就是说如果说一个类被不同的加载器加载,那么就相当于是两个不同的类。所以我们需要保证同一个类不会被不同的加载器加载,这时候就需要使用双亲委派模型。

2.定义:每当一个类加载器接收到加载请求时,它会先将请求转发给父类加载器,在父类加载器没有找到请求的该类的情况下,该加载器才会去加载此类;也就是由下到上逐级委托,然后在由上到下逐级查找。

四、类的卸载

触发类的卸载的两个条件:1.该Class所有的实例都已经被GC掉了;2.加载该类的ClassLoader实例已经被GC;

验证方法:在jvm启动中增加-verbose:class参数,输出类加载和卸载的日志信息。

你可能感兴趣的:(java)