java虚拟机--invokedynamic指令简单分析

invokedynamic指令是java7引入的。这是自 1.0 以来第一次引入新的虚拟机指令。到了 java 8 这条指令才第一次在 java 应用,用在 lambda 表达式里。在这之前的方法调用指令为 invokestatic、invokespecial、invokevirtual、invokeinterface。这四种指令和包含目标方法类名,方法名以及方法描述符的符号引用绑定。为了实现invokedynamic,java7引入了更底层,更灵活的方法抽象:方法句柄。

方法句柄的概念

方法句柄是一个强类型,可以直接执行的引用。方法句柄的类型是由所指向方法的参数类型和返回类型组成。它是用来确认方法句柄是否适配的唯一关键。方法句柄的功能与反射想类似。下面从不同的角度对比一下反射-代理-方法句柄

  1. 反射需要调用setAccesible(),可能会受到禁止警告,代理类如果是内部类创建,就只能访问受限的函数和方法,而方法句柄在访问的上下文中对所有方法都拥有完整的权限。
  2. 反射的执行速度回受可变长的参数,基本类型的自动装拆箱,以及最重要的方法内联的影响,代理调用的方法和调用函数的方式是一样的,速度最快,方法句柄自然不可能有代理的执行速度,它的速度受jvm的各类配置所影响。

方法句柄的操作

方法句柄的调用有两种,一种是需要严格匹配参数类型的invokExact:假设一个方法句柄需要接受一个Object类型的参数,如果你传入一个String类型的参数,那么在运行时就会抛出异常。但方法句柄API有个注解@PolymorphicSignature,如果被调用的方法有这个注解的话,编译器会根据所所传入的参数来生成方法描述符,而不是采用目标方法的方法描述符。

另一种是invoke,可以自动适配参数类型。invoke方法会调用MethodHandle.asType方法,生成一个适配器句柄。在调用目标方法时先进行适配,然后再返回给调用者。

方法句柄的操作

jvm在调用invokExact方法的时候,会调用一个共享的、与方法句柄类型相关的特殊适配器LambdaForm当中。当然,要想看这个类的话,可以添加启动参数  -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FIFLE=true 来导出这个类的class文件。

在LambdaForm中会调用Invokers.checkExactType去检查参数类型,然后调用Invokes.CheckCustomized方法。最后,调用方法句柄的invokeBasic方法。invokeBasic同样会被jvm特殊对待,执行时,会调用到方法句柄本身所持有的适配器里,也是一个LambdaForm。这个LambdaForm会获取方法句柄里的MemberName字段,作为参数调用linkToStatic方法。当然,linkToStatic也会做特殊处理,会根据传入的参数 储存的索引  直接跳转到目标方法。  在这些方法里 Invokes.CheckCustomized在超过 一个阈值时就会进行优化  阈值可用参数 -Djava.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD进行设置,默认是127.当调用次数大于这个阈值的时候,Invokes.CheckCustomized会为该方法句柄生成一个特有的适配器,这个适配器就会将方法句柄作为常量 直接获取MemberName类型的字段 供linkToStatic调用。

方法句柄的调用和反射一样,都是间接调用,因此  ,会被无法进行方法内联而影响性能。不过,方法句柄的内联瓶颈在于JIT能否将方法句柄作为常量。下面,就来具体的讲讲

invokedynamic指令

invokedynamic是java7引入的新指令,主要是用来支持动态语言的方法调用。将调用点 抽象成一个java类,并将原本由jvm控制的方法调用以及方法链接暴露给了应用程序。在运行过程中,每条invokedynamic指令都会绑定一个调用点,且会调用该调用点链接的方法句柄。在第一次执行invokedynamic时,jvm会调用该指令对应的启动方法,来生成调用点,并绑定到invokedynamic指令里。之后再次运行的话,就直接调用绑定的调用点链接的方法句柄。

----------------------------------------------------------------------------------------------------------------待更新

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值