深入理解java解析、分派和绑定

来源:互联网 发布:广州红砖厂淘宝摄影 编辑:程序博客网 时间:2024/06/08 00:00
1, 解析
解析是虚拟机将常量池内的符号引用替换为直接引用的过程。类的加载过程:加载,验证,准备,解析,初始化,使用,卸载。七个阶段顺序开始,交叉进行
直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。简单来讲,解析就是从字面符号到内存地址,从内存无关到内存有关的过程。
虚拟机规范之中并未规定解析阶段发生的具体时间,只要求了在执行anewarray、checkcast、getfield、getstatic、instanceof、invokedynamic、invokeinterface、invokespecial、invokestatic、invokevirtual、ldc、ldc_w、multianewarray、new、putfield和putstatic这16个用于操作符号引用的字节码指令之前,先对它们所使用的符号引用进行解析。所以虚拟机实现可以根据需要来判断到底是在类被加载器加载时就对常量池中的符号引用进行解析,还是等到一个符号引用将要被使用前才去解析它。据此,可以将解析分为立即解析惰性解析
对同一个符号引用进行多次解析请求是很常见的事情:
  • 静态解析:发生在指令执行前。直接操作字节流Class文件的常量池。除invokedynamic指令以外,虚拟机实现可以对第一次解析的结果进行缓存(在运行时常量池中记录直接引用,并把常量标识为已解析状态)从而避免解析动作重复进行。静态解析具有幂等性,即同一个实体中的同一个符号引用,第一次成功后续皆成功;同样的,第一次失败后续皆异常——相同异常。包括立即解析惰性解析。
  • 动态解析:发生在指令执行中。操作的是方法区中的运行时常量池。对于invokedynamic指令,上面规则则不成立。当碰到某个前面已经由invokedynamic指令触发过解析的符号引用时,并不意味着这个解析结果对于其他invokedynamic指令也同样生效。因为invokedynamic指令的目的本来就是用于动态语言支持,这里“动态”的含义就是必须等到程序实际运行到这条指令的时候,解析动作才能进行。相对的,其余可触发解析的指令都是“静态”的,可以在刚刚完成加载阶段,还没有开始执行代码时就进行解析。
注意:
阅读全文
0 0