JVM-类的加载

类的加载步骤

JVM加载类的过程大致分为三步,装载(Load),连接(Link),初始化(Initialize)
这里写图片描述

  • 装载:加载类的二进制文件(将.class加载如内存)

    • 通过一个类的全限定名来获取定义此类的二进制字节流。
    • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
    • 在java堆中生成一个代表这个类的java.lang.Class对象,做为方法区这些数据的访问入口。
    • 加载阶段完成之后二进制字节流就按照虚拟机所需的格式存储在方区去中。
  • 验证:确保呗加载类的正确性(验证.class的正确性)

    • 【文件格式验证】验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。
    • 【元数据验证】对字节码描述的信息进行语义分析,以确保其描述的信息符合java语言规范的要求。
    • 【字节码验证】这个阶段的主要工作是进行数据流和控制流的分析。任务是确保被验证类的方法在运行时不会做出危害虚拟机安全的行为。
    • 【符号引用验证】这一阶段发生在虚拟机将符号引用转换为直接引用的时候(解析阶段),主要是对类自身以外的信息进行匹配性的校验。目的是确保解析动作能够正常执行。
  • 准备:为类的静态变量分配内存并初始化
    • 这些内存都将在方法区中进行分配
    • 这里的变量仅包括类标量不包括实例变量
  • 解析:将类的符号引用变为直接引用
    • 【符号引用】符号引用以一组符号来描述所引用的目标,符号可以是任意形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。
    • 【直接引用】直接引用可以是直接指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。直接饮用是与内存布局相关的。
  • 初始化:为类的静态变量赋予正确的值

类的加载时机

类的加载时机有一下六种:

  • 创建类的实例的时候,也就是使用new创建对象的时候
  • 访问某个类或接口的静态变量的时候,或者对该静态变量赋值的时候
  • 调用类的静态方法的时候
  • 反射
  • 初始化类的子类的时候(会首先初始化子类的父类,接口加载时则无需加载所有父接口)
  • JVM启动时的启动类
  • 运行时计算生成,最典型的是动态代理技术

注意:虚拟机规范并没有指明二进制字节流要从一个Class文件获取,或者说根本没有指明从哪里获取、怎样获取。这种开放使得Java在很多领域得到充分运用,例如:

从ZIP包中读取,这很常见,成为JAR,EAR,WAR格式的基础
从网络中获取,最典型的应用就是Applet
运行时计算生成,最典型的是动态代理技术,在java.lang.reflect.Proxy中,就是用了ProxyGenerator.generateProxyClass来为特定接口生成形式为“*$Proxy”的代理类的二进制字节流
有其他文件生成,最典型的JSP应用,由JSP文件生成对应的Class类

加载器-类型

JVM默认有三种类的加载器
- 【启动类加载器】使用C++代码实现(不是Java类,因此它不需要被别人加载),嵌套在Java虚拟机内核里面,也就是JVM启动的时候Bootstrap就已经启动,例如java.lang等包下的类
- 【扩展类加载器】负责载入标准扩展目录中的类,例如Sun的JVM的扩展目录是/jdk/jre/lib/ext。
- 【系统类加载器】默认的类加载器,搜索环境变量CLASSPATH中指明的路径。

类的加载其他注意事项:

【自定义类的加载器】

  • 默认很多情况下应用程序会根据自身需求定义自己的类的加载器,如tomcat根据j2ee标准自行实现ClassLoader。

【类的卸载】

  • 就是Class文件的垃圾回收,系统自带的类的加载器加载的类不会被回收。

【命名空间】

  • 类使用命名空间(类的包名+类的加载器)确定类的唯一性
  • 同一命名空间下的类是相互可见的
  • 子类命名空间包含父类的命名空间,因此由子类加载器记载的类能“看到”由父类加载器加载的类
  • -

类的加载机制(双亲委派机制)

通俗来讲就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
这里写图片描述

为什么要让父类加载器优先去加载呢?
试想如果子类加载器先加载,那么我们可以写一些与java.lang包中基础类同名的类,
然后再定义一个子类加载器,这样整个应用使用的基础类就都变成我们自己定义的类了。这样就有很大的安全隐患!
所以自己编写类加载器时,如果没有特殊原因,一定要遵守类加载的双亲委派模型。

。。。未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值