您的位置:首页 > 其它

Jvm(52),虚拟机类加载机制----类加载的过程----加载

2018-09-22 22:18 501 查看

"加载"是"类加载"(Class Loading)过程的一个阶段,希望读者没有混淆这两个看起来很相似的名词。在加载阶段,虚拟机需要完成以下3件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

虚拟机规范的这3点要求其实并不算具体,因此虚拟机实现与具体应用的灵活度都是相当大的。例如"通过一个类的全限定名来获取定义此类的二进制字节流"这条,它没有指明二进制字节流要从一个Class文件中获取,准确地说是根本没有指明要从哪里获取、怎样获取。

虚拟机设计团队在加载阶段搭建了一个相当开放的、广阔的"舞台",Java发展历程中,充满创造力的开发人员则在这个"舞台"上玩出了各种花样,许多举足轻重的Java技术都建立在这一基础之上,例如:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。

从ZIP包中读取,这很常见,最终成为日后JAR、EAR、WAR格式的基础。

从网络中获取,这种场景最典型的应用就是Applet。

运行时计算生成,这种场景使用得最多的就是动态代理技术,在java.lang.reflect.Proxy

中,就是用ProxyGenerator.generateProxyClass来为特定接口生成形式为"*$Proxy"的代理类的二进制字节流。由其他文件生成,典型场景是JSP应用,即由JSP文件生成对应的Class类。

从数据库中读取,这种场景相对少见些,例如有些中间件服务器(如SAP Netweaver)可以选择把程序安装到数据库中来完成程序代码在集群间的分发。

  1. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  2. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

加载阶段完成后,虚拟机外部的二进制字节流就按照虚拟机所需的格式存储在方法区之中,

方法区中的数据存储格式由虚拟机实现自行定义,虚拟机规范未规定此区域的具体数据结

构。然后在内存中实例化一个java.lang.Class类的对象(并没有明确规定是在Java堆中,对于HotSpot虚拟机而言,Class对象比较特殊,它虽然是对象,但是存放在方法区里面),这个对象将作为程序访问方法区中的这些类型数据的外部接口。

加载阶段与连接阶段的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: