jvm类的加载

一、类加载器作用

 类加载器子系统负责从文件系统或者网络中加载class文件,class文件在文件开头都有特定标识。

类加载子系统只负责加载文件,而这个class是否能运行则由执行引擎决定。

加载类信息存放在方法区,除了类信息外,方法区还存放运行时常量池信息,可能还包括字符串字面量和数字常量。

二、类加载子系统的作用

        1.字节码文件存在于本地硬盘上,需要加载到jvm上运行,根据这个模板实例化出n个一摸一样的实例。

        2.字节码被加载到jvm存放在方法区,称为DNA元数据模板,在从字节码文件->jvm->DNA元数据模板,需要一个运输工具,类加载就起到了这个作用。

三、类的加载过程

 加载:
        1.通过一个类的全限制名获取此类的二进制字节流。

        2.将这个字节流的静态存储转换为方法区的运行时数据结构。

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

验证:

        1.目的在于确保当前加载的字节码信息符合虚拟机要求,保证被加载类的正确性,确保不会危害虚拟机自身安全。

        2.主要包括四种验证:文件格式验证、字节码验证、元数据验证、符号引用验证。

准备:

        1.为类变量分配内存并且设置该类变量的默认初始值。

        2。这里不包含用final修饰的static,因为final在编译的阶段就会分配了,准备的阶段会显式初始化。

        3.这里不会为实例变量分配初始化,类变量会分配到方法区中,实例变量会随对象分配到java堆中。

解析:

        1.将常量池中的符号引用转换为直接引用的过程。

        2.事实上,解析操作往往会伴随jvm在执行完初始化之后再执行。

        3.符号引用就是用一组符号来描述目标,直接引用就是直接指向目标的指针,相对偏移量或间接定位到目标的句柄。

        4.解析引用主要针对类或接口,字段,类方法,接口方法,方法类型等。

初始化:

        1.初始化阶段就是执行类构造器方法<clinit>()的过程。

        2.此方法不需要定义,是javac不断收集类中所有类变量的赋值以及静态代码块中的语句合并而来。

        3.构造器中的指令按照在源文件中的出现顺序执行。

        4.若该类具有父类,<clint>()会保证子类的<clinit>()执行前,父类的<clinit>()已经执行。

        5.虚拟机必须保证一个类的<clinit>()方法,在多线程下被同步加锁。

四、类加载器的分类

jvm支持两种类加载器,分别是引导类加载器,自定义类加载器。我们将所有派生于ClassLoader的类加载器都划分为自定义加载器。无论加载器如何划分,在程序中,我们常见的类加载器如下。

 

         这里的四者之间是包含关系,不是上下层关系,也不是父子类继承关系。

        对于用户自定义类来说,默认使用系统类加载器进行加载。

        java的核心类库都是使用引导类加载器进行加载的。

五、虚拟机自带的类加载器

        1.引导类加载器

        这个类加载器是使用C/C++完成的,它用来加载java的核心库,用于提供jvm自身需要的类。并不继承自java.lang.ClassLoader,没有父加载器。出于安全考虑,引导类加载器只能加载以sun、java、javax等开头的类。

        2.扩展类加载器

        java语言编写,派生于ClassLoader类,父类加载器为引导类加载器。从java.ext.dirs系统属性所指定的目录的jre/lib/ext子目录中加载类库。如果用户创建的jar放在此目录下,也会自动由扩展类加载器加载。

        3.系统类加载器

        java语言编写,派生于ClassLoader类,父类加载器为引导类加载器。它负责加载环境变量classpath或系统属性,java.class.path指定路径下的类库。

        该类加载器是java中的默认加载器,一般来说java应用的类都是由它来完成加载。

在java的开发中,类加载器几乎都是由以上三种类加载器配合执行的,除此之外我们还可以自定义类加载器,来制定类的加载方式。

 为什么要自定义类的加载类?

  • 隔离加载类
  • 扩展加载源
  • 修改类加载的方式
  • 防止源码泄露

六、双亲委派机制

        java虚拟机对class文件采用按需加载的方式,即当需要使用该类时才会将该类加载到内存当中生成class对象。而且加载某个类的class文件时,java虚拟机采用的是双亲委派模式,即把请求交给父类处理,它是一种任务委派模式。

        

工作原理:

        如果一个类加载器收到了类加载请求,它并不会自己去加载,而是将这个请求委托给父类的加载器去执行,如果父类还存在父类加载器,则进一步向上委托,递归直到引导类加载器。

        如果父类加载器能完成类的加载任务就成功返回,倘若父类加载器无法完成加载任务,子类加载器才会尝试自己加载。

优势:

        避免类的重复加载。

        保护程序安全,防止核心API被随意篡改。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值