网站建设类毕业设计,平面设计培训机构排名,资讯类网站模板,用html制作淘宝网页栈顶缓存技术#xff08;Top-of-Stack Cashing#xff09;
前面提过#xff0c;基于栈式架构的虚拟机所使用的零地址指令更加紧凑#xff0c;但完成一项操作的时候必然需要使用更多的入栈和出栈指令#xff0c;这同时也就意味着将需要更多的指令分派(instruction dispatc…栈顶缓存技术Top-of-Stack Cashing
前面提过基于栈式架构的虚拟机所使用的零地址指令更加紧凑但完成一项操作的时候必然需要使用更多的入栈和出栈指令这同时也就意味着将需要更多的指令分派(instruction dispatch)次数和内存读/写次数由于操作数是存储在内存中的因此频繁地执行内存读/写操作必然会影响执行速度。为了解决这个问题Hotspot JVM的设计者们提出了栈顶缓存(ToS,Top-of-Stack Cashing)技术将栈顶元素全部缓存在物理CPU的寄存器中以此降低对内存的读/写次数提升执行引擎的执行效率
方法的调用
静态链接与动态链接
在JVM中将符号引用转换为调用方法的直接引用与方法的绑定机制相关。
静态链接
当一个字节码文件被装载进JVM内部时如果被调用的目标方法在编译期可知且运行期保持不变时。这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。
动态链接
如果被调用的方法在编译期无法被确定下来也就是说只能够在程序运行期将调用方法的符号引用转换为直接引用由于这种引用转换过程具备动态性因此也就被称之为动态链接。
早起绑定与晚期绑定
对应的方法的绑定机制为早期绑定(Early Binding)和晚期绑定(Late Binding)。绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程这仅仅发生一次。
早期绑定
早期绑定就是指被调用的目标方法如果在编译期可知且运行期保持不变时即可将这个方法与所属的类型进行绑定这样一来由于明确了被调用的目标方法究竞是哪一个因此也就可以使用静态链接的方式将符号引用转换为直接引用。
晚期绑定
如果被调用的方法在编译期无法被确定下来只能够在程序运行期根据实际的类型绑定相关的方法这种绑定方式也就被称之为晚期绑定。
虚方法与非虚方法
随着高级语言的横空出世类似于Java一样的基于面向对象的编程语言如今越来越多尽管这类编程语言在语法风格上存在一定的差别但是它们彼此之间始终保持着一个共性那就是都支持封装、继承和多态等面向对象特性既然这一类的编程语言具备多态特性那么自然也就具备早期绑定和晚期绑定两种绑定方式。
Java中任何一个普通的方法其实都具备虚函数的特征它们相当于c语言中的虚函数(c中则需要使用关键字virtual来显式定义)。如果在Java程序中不希望某个方法拥有虚函数的特征时则可以使用关键字final来标记这个方法。
非虚方法
如果方法在编译期就确定了具体的调用版本这个版本在运行时是不可变的。这样的方法称为非虚方法。
静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法。
其他方法称为虚方法。 虚拟机中提供了以下几条方法调用指令
普通调用指令
invokestatic:调用静态方法解析阶段确定唯一方法版本invokespecial:调用init方法、私有及父类方法解析阶段确定唯一方法版本invokevirtual:调用所有虚方法invokeinterface:调用接口方法
动态调用指令
invokedynamic:动态解析出需要调用的方法然后执行前四条指令固化在虚拟机内部方法的调用执行不可人为千预而invokedynamic指令则支持由用户确定方法版本。其中invokestatic指令和invokespecial指令调用的方法称为非虚方法其余的(final修饰的除外)称为虚方法。 JVM字节码指令集一直比较稳定一直到Java7中才增加了一个invokedynamic指令这是Java为了实现「动态类型语言」支持而做的一种改进。
但是在Java7中并没有提供直接生成invokedynamic指令的方法需要借助ASM这种底层字节码工具来产生invokedynamic指令。直到Java8的Lambda表达式的出现invokedynamic指令的生成在Java中才有了直接的生成方式。
Java7中增加的动态语言类型支持的本质是对Java虚拟机规范的修改而不是对Java语言规则的修改这一块相对来讲比较复杂增加了虚拟机中的方法调用最直接的受益者就是运行在Java平台的动态语言的编译器。
动态类型语言和静态类型语言
动态类型语言和静态类型语言两者的区别就在于对类型的检查是在编译期还是在运行期满足前者就是静态类型语言反之是动态类型语言。
说的再直白一点就是静态类型语言是判断变量自身的类型信息动态类型语言是判断变量值的类型信息变量没有类型信息变量值才有类型信息这是动态语言的一个重要特征。
方法重写的本质
Java语言中方法重写的本质
找到操作数栈顶的第一个元素所执行的对象的实际类型记作C。如果在类型C中找到与常量中的描述符合简单名称都相符的方法则进行访问权限校验如果通过则返回这个方法的直接引用查找过程结束如果不通过则返回java.lang.IllegalAccessError异常。否则按照继承关系从下住上依次对C的各个父类进行第2步的搜索和验证过程。如果始终没有找到合适的方法则抛出java.lang.AbstractMethodError异常。IllegalAccessError介绍
程序试图访问或修改一个属性或调用一个方法这个属性或方法你没有权限访问。一般
的这个会引起编译器异常。这个错误如果发生在运行时就说明一个类发生了不兼容的
改变。
虚方法表
在面向对象的编程中会很频繁的使用到动态分派如果在每次动态分派的过程中都要重新在类的方法元数据中搜索合适的目标的话就可能影响到执行效率。因此为了提高性能JVM采用在类的方法区建立一个虚方法表(virtual method table)(非虚方法不会出现在表中)来实现。使用索引表来代替查找。
每个类中都有一个虚方法表表中存放着各个方法的实际入口。
那么虚方法表什么时候被创建
虚方法表会在类加载的链接阶段被创建并开始初始化类的变量初始值准备完成之后JVM会把该类的方法表也初始化完毕。