方法的绑定机制
早起绑定
晚期绑定
可以看具体例子-com.study.jvm.stack.localvariables.LocalVariables
补充说明
在栈帧中,与性能调优关系最密切的部分就是局部变量表
局部变量中的变量也是重要的垃圾回收的根节点,只要被局部变量表中直接或间接引用的对象都不会被回收
由于高级语言具备多态的特性,那么就具备早起绑定和晚期绑定两种绑定方式
com.study.jvm.stack.localvariables.LocalVariables
方法调用的指令
invokestatic:调用静态方法,解析阶段确定唯一方法版本(属于静态链接)
invokespecial:调用<init>方法、私有方法及父类方法,解析阶段确定唯一法版本(属于静态链接)
invokevirtual:调用所有虚方法(除去final修饰的方法外都属于动态链接)
invokeinterface:调用所有接口方法(属于动态链接)<br>
invokeDynamic:动态解析出需要调用的方法,然后执行(属于动态链接)
语言
静态语言
例如java:String str = “你好”;//如果不定义类型就会报错 重新赋与其他类型的值也会报错 str = 10;//错误
动态语言
例如JS: var name = "这是个字符串"// 后期一个队这个重新赋值 name = 10;
例如Python: info = 123.3; info = "张三"; //这里连参数的类型都不需要定义
方法调用
方法重写的本质
找到操作数栈顶的第一个元素所执行对象的实际类型,记做E
在类型E中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限效验,如果通过则返回这个方法的直接引用,查过程结束;如果不通过,则返回java.lang.IllegalAccessError异常
否则继承关系从下往上依次E的各个父类进行第二部的搜索和验证过程
如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError
虚方法表
为了提高性能(避免每次都往父类找),在方法区建立一个虚方法表(virtual method table)(非虚方法不会出现在表中,非虚方法是编译时就确定了调用方法就确定了)
虚方法表是在链接的阶段就产生的(在链接阶段中的解析阶段(符号引用转换为直接引用))