Java类加载过程

前言:

一个java文件从被加载到被卸载这个生命过程
        加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载
类的加载全过程:
        加载->验证->准备->解析->初始化
详情:
    1,首先是加载:

        这一块虚拟机要完成3件事:

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

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

            3.在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。
                
        说明关于第一点,很灵活,很多技术都是在这里切入,因为它并没有限定二进制流从哪里来:
                    从class文件来->一般的文件加载
                    从zip包中来->加载jar中的类
                    从网络中来->Applet
    2,加载完成后就要开始对那些字节流进行检验

        检验的目的:确保class文件的字节流信息符合jvm的口味,不会让jvm感到不舒服。

        检验主要经历几个步骤:文件格式验证->元数据验证->字节码验证->符号引用验证

            文件格式验证:验证字节流是否符合Class文件格式的规范并验证其版本是否能被当前的jvm版本所处理。ok没问题后,字节流就可以进入内存的方法区进行保存了。后面的3个校验都是在方法区进行的。

            元数据验证:对字节码描述的信息进行语义化分析,保证其描述的内容符合java语言的语法规范。

            字节码检验:校验java编译成的字节码文件是否破损或格式错误

            符号引用验证:来验证一些引用的真实性与可行性,比如代码里面引了其他类,这里就要去检测一下那些来究竟是否存在;或者说代码中访问了其他类的一些属性,这里就对那些属性的可访问性进行检验。(这一步将为后面的解析工作打下基础)

    3,接着就上面步骤完成后,就会进入准备阶段了:

        这阶段会为类变量(指那些静态变量)分配内存并设置初始值的阶段,这些内存在方法区中进行分配。这里不包含用final修饰的static,因为final在编译的时候就会分配了

    4,完成上步后,就要进行解析了。解析好像是对类的字段,方法等东西进行转换,具体涉及到Class文件的格式内容,并没深入去了解。

    5,在前面的类加载过程中,除了在加载阶段用户可以通过自定义类加载器参与之外,其他的动作完全有jvm主导,到了初始化这块,才开始真正执行java里面的代码。这一步将会执行一些预操作,注意区分在准备阶段,已经为类变量执行过一次系统赋值了。其实说白了,这一步就是执行程序的构造器

这里电脑只写了文本版本,后期更新一个Xmind思维导图,,,

猜你喜欢

转载自my.oschina.net/lovexin/blog/1802490