通过一个类的全限定名来获取定义此类的二进制字节流(并没有指明要从一个Class文件中获取,可以从其他渠道,譬如:网络、动态生成、数据库等);将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;
加载阶段和连接阶段()的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序 。
验证
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全 。
验证阶段是非常重要的,这个阶段是否严谨,直接决定了Java虚拟机是否能承受恶意代码的工具,从执行性能的角度上讲,验证阶段的工作量在虚拟机的类加载子系统中又占了相当大一部分 。
验证阶段大致会完成4个阶段的检验动作:
文件格式验证:验证字节流是否符合Class文件格式的规范,并且能够被当前版本的虚拟机处理 元数据验证:对字节码描述的信息进行语义分析(注意:对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求; 字节码验证:整个验证过程最复杂的一个阶段 。主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的 。在第二阶段对元数据信息中的数据类型做完校验后,这个阶段将对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的事件 符号引用验证:目的是确保解析动作能正常执行,发生在虚拟机将符号引用转换为直接引用的时候,这个转化动作将在连接的第三阶段-解析阶段中发生 。符号引用验证可以看做是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验 。
验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用-参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间 。
准备
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配 。这时候进行内存分配的仅包括类变量(被修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中 。其次,这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:
public static int value=http://www.kingceram.com/post/123;
那变量value在准备阶段过后的初始值为0而不是123.因为这时候尚未开始执行任何java方法,而把value赋值为123的指令是程序被编译后,存放于类构造器()方法之中,所以把value赋值为123的动作将在初始化阶段才会执行 。
至于“特殊情况”是指:
public static final int value=http://www.kingceram.com/post/123
即当类字段的字段属性是时,会在准备阶段初始化为指定的值,所以标注为final之后,value的值在准备阶段初始化为123而非0.
解析
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程 。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行 。
初始化
类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的java程序代码 。在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序猿通过程序制定的主观计划去初始化类变量和其他资源,或者说:初始化阶段是执行类构造器()方法的过程 。
- 【深入理解JVM 六】虚拟机字节码执行系统
- 自古帝王多好色:揭秘慈禧太后的获宠之路
- 海上丝绸之路的途经国家是哪些分别是哪些国家
- 专访国内顶级商业操盘手卞波,从一年做到10个亿的企业家到谆谆传教者的进阶之路
- 史海峰:成为技术领导者 从技术到管理的必经之路丨声网开发者创业讲堂 ? 第 5
- 揭开汉文帝刘恒的继位之路:步步为营才终登皇位
- 唐玄宗李隆基如何开创他的帝王之路
- 史上最倒霉皇帝:宋光宗赵惇被老婆逼成神经病
- 尼泊尔发现千年中印衣料丝绸之路或将延长
- 揭秘:丝绸之路上的千年干尸之谜