问题标签 [invokedynamic]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 调用动态的 Groovy 性能问题?
我正在努力确定是什么导致了一个中等大小的 Groovy 应用程序在生产中运行缓慢。当获取正在运行的应用程序的线程转储时,我看到的奇怪的事情是很多线程都有这样的堆栈跟踪:
我在网上看到有人提到该setCallSiteTargetNormal
方法是相当重量级的,并且在调用它时会阻塞所有 JVM 线程。我们使用 Groovy 的调用动态支持,我想知道我们是否遇到了 Groovy 中的某种错误,导致该方法被过度调用。
我已经检查过的明显性能问题:
- 内存使用没问题
- GC 开销是正常的
- 服务器上的 CPU 使用率看起来还不错
- 外部数据库和网络服务调用都正常
关于 CPU 使用率的一个注意事项是,该应用程序的行为就像它需要 CPU 一样,但它只使用了 4 CPU 机器的总 CPU 的大约 1/4。它的行为就像一个线程应该 100% 与 CPU 挂钩,但我根本没有看到这一点。然而,我在网上找到的一些信息表明setCallSiTeTargetNormal
方法调用完全阻塞了 JVM 上的所有线程。
java - 使用 MethodHandles 和 invokedynamic 链接方法调用
想一想动态的、谓词方面的语言。可以调用方面(即方法)来代替或在原始方法之前和之后调用。这些方面在运行时打开和关闭。甚至可能是多个方面想要更改同一个方法,这将导致这些方面组合成一个方法调用链。
原始方法由加载时编译器(JPLIS 和 ASM)更改。我得到了一些看起来像这样的字节码:
有趣的部分是引导方法应该以特定方式工作:
- 返回具有兼容参数列表的方法串联。这些
MethodHandle
s 绑定到调用它们的不同类型的不同实例。 - 结果可能
MethodHandle
只是绑定到其他实例,而不是绑定到调用引导方法的实例。因此,应该省略使用this调用生成的调用站点(下面替代方案中的第一个分支)。
也有可能直接调用原来的方法,完全没问题。
在我看来,MethodHandle
s 是实现这一目标的正确方法。我的问题是,如果一切都可以在单个引导方法中实现,那么我可以使用从绑定到调用站点的引导方法返回的方法句柄链来链接方法调用,如序列图中所示。
java - Java 9 中如何实现字符串连接?
如JEP 280 中所写: Indify String Concatenation:
更改
String
生成的静态连接字节码序列javac
以使用invokedynamic
对 JDK 库函数的调用。这将使未来的String
连接优化成为可能,而无需进一步更改javac
.
在这里我想了解invokedynamic
调用的用途是什么以及字节码连接有什么不同invokedynamic
?
java - 调用方法时Java中的调用站点是什么?
我试图了解什么是 JVM 中的调用站点。引用自https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.6
调用站点说明符解析的结果是一个元组,包括:
• 对 的实例的引用
java.lang.invoke.MethodHandle
,• 对 的实例的引用
java.lang.invoke.MethodType
,
Class
• 对、java.lang.invoke.MethodHandle
、java.lang.invoke.MethodType
和的实例的引用String
。
我们还有所谓的调用站点对象https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic:
bootstrap 方法返回的结果必须是对类为 的对象
java.lang.invoke.CallSite
或其子类 的引用java.lang.invoke.CallSite
。此对象称为调用站点对象
调用站点对象的概念很明确。这只是CallSite
. 但是调用站点说明符呢?那是一个Java对象吗?那是String
字面意思吗?
android - android sdk <26(奥利奥)上的`invokedynamic`?
有没有办法invokedynamic
在比 sdk 级别 26(即 Oreo、Android 8)的旧版本上使用?即只需安装较新的VM (ART) 版本。
因为它是一个 VM 功能,它不会独立于所有非 VM sdk 级别 26 功能,并且可以在任何版本的 android 上运行吗?
PS 这是为了让kotlin 编译器在 android 上运行。
java - 如何使用 LambdaMetaFactory 调用构造函数?
我想尝试避免反射调用构造函数,并尝试遵循本文中采用的 LamdaMetaFactory 方法 - Java 反射的更快替代方案
我要构建的课程如下所示:
使用LambaMetaFactory
我正在尝试构造一个BiFunction<BrokerPool, Configuration, DBBroker>
来替换对构造函数的直接调用。
到目前为止,我的代码如下所示:
不幸的是,这会返回错误-
AbstractMethodError: 方法 org/exist/storage/BrokerFactory$$Lambda$55.apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; 是抽象的。
我已经尝试修改传递给的各种类型,LambdaMetafactory.metafactory
但我似乎不能完全正确地做到这一点,而且 Javadoc 肯定不容易理解。
有人可以建议吗?
java - 通过公共查找检索数组克隆方法句柄
最近尝试通过库来访问clone
数组类型的方法。java.lang.invoke
这被证明是不成功的。示例中的克隆方法是这样的:
我希望MethodHandle
为a.clone()
通话创建一个。这样生成的代码类似于:
我为所有其他方法调用设置了这个系统。但是,仅使用这种方法,系统就会失败。
这个问题与java.lang.invoke
图书馆有关,而不是java.lang.reflect
图书馆。
问题描述
引入了以下示例代码来显示此行为。
样本输出:
查找:主要
mh:方法句柄(主)对象
输出是有道理的。范围内的调用者Main
只能看到的超类clone
中的方法Main
:Object
。即使int[]
用作参考类,此方法也是不可见的。这成为一个问题,因为如果使用此调用站点,JVM 会尝试强制转换int[]
为Main
.
通过将引用类型引入为int[]
,人们会期望clone
type 中的方法int[]
是可公开访问的。因此,当文档建议时:
方法句柄的类型将是方法的类型,并带有接收者类型(通常是 refc)。1
的类型mh
将是(int[])Object
。
尝试的解决方案:
由于查找caller
通过遮蔽正确的clone
方法进行干扰,因此尝试使用公共查找:
然而,这失败了。Object#clone()
对签名的简单检查说明了原因:
方法是protected
。这不适用于数组类型,因为实现使该方法公开可用。
这方面的一个例子是尝试访问该Object#equals
方法。这与三个单独的参考类一起显示:
查找:java.lang.Object/public
mh:方法句柄(对象,对象)布尔
然后Main.class
用作参考类:
查找:java.lang.Object/public
mh:方法句柄(主要,对象)布尔
然后int[].class
用作参考类:
查找:主要
mh: MethodHandle(int[],Object)boolean
这是预期的行为,显然可以流畅地工作。在第一种情况下,引用类是Object
并且它返回Object#equals
方法句柄。第二个是引用类Main
,它返回Main#equals
方法句柄。最后,引用类是int[].class
并且它返回了int[]#equals
方法句柄。
但是,该方法不能保持这种奇偶性int[]#clone
。由于该clone
方法是受保护的,但对于数组是公共的,因此无法找到它。对我来说,这似乎是一个错误。数组clone
方法应该通过publicLookup
. 返回的方法句柄类型可能是:MethodHandle(Object)Object
。
一旦检索到,MethodHandle#asType
然后可以用于更正类型。在这种情况下,它将被转换为MethodHandle(int[])Object
.
如果没有Object#clone
公开可用的方法,至少对于数组类型,这似乎是不可能的。
此外,这似乎是唯一可能发生这种情况的方法,因为数组类型仅扩展/实现 3 个类Object
:Cloneable
和Serializable
. 唯一的其他方法Object#finalize
也是受保护的;但是,数组类型不会公开此方法。因此clone
,这是唯一失败的方法。
tl;博士:
数组clone
方法,例如Object[]#clone()
,不能通过公共查找公开访问。这是因为Object#clone
是protected
;但是,数组类型使此方法公开可用。clone
由于此可见性问题,尝试通过引用类访问数组失败。因此,MethodHandle
无法为此方法生成 a。但是,在公共方法上尝试相同的技术,例如Object#equals
对数组类型效果很好。
我宁愿避免反射访问,因为方法可以通过简单地更改查找的信任级别来检索它。
有没有办法MethodHandle
为数组clone
方法生成一个?
注意:我确实了解 的正确用法,java.lang.invoke
并且我不打算将其用作java.lang.reflect
.
groovy - 为什么 Invokedynamic 不是 Groovy 中的默认设置?
Groovy--indy
在 2012 年的 2.0 版中添加了该选项。当时它不是默认设置,因为invoke dynamic
需要 Java 7,而且当时很多人使用 Java 6。
现在即使是即将推出的 Groovy 3.0 仍然需要该--indy
选项才能强制它使用invoke dynamic
. 尽管 Groovy 3.0 需要 Java 8 或更高版本,但还是会这样。
仍然具有默认的非 indy 编译和默认的运行时库是非 indy 是否有任何技术优势?我会认为现在甚至不需要非独立选项。
java - 如何使用 ASM 生成模拟 invokevirtual 的 invokedynamic 调用
我想看看如何invokedynamic
使用与invokevirtual
.
我问这个问题是因为目前在线使用 ASM 生成动态方法调用的示例太琐碎而无法概括,我认为这种情况对于任何想要实现自己的调度逻辑的人来说都是一个很好的起点。
显然,我知道在实践中仅仅用一个替换invokevirtual
调用invokedynamic
将是一件毫无意义的事情。
要清楚,我想替换它:
有了这个:
// 引导方法
java - 使用“invokedynamic” - 引擎盖下发生了什么?
背景
我目前正在用 C# 编写一个 JVM,纯粹是为了学术目的(将来可能会构建一个混合的 .NET 和 Java/Scala 应用程序)。
语境
我编写了简单的JAVA类:
并将其编译成test.class
. 当我用我的反编译器(我作为 JVM 的一部分编写的)反编译它时,我看到了这个方法的以下说明:
在常量池中查看 index 处的常量时2
,我看到一个 InvokeDynamic-Constant 条目,其中包含以下数据:
我想这是有道理的(我更像是 .NET 用户而不是 JAVA 用户)。
hello_world
使用参数执行我的方法时1
,在执行之前我有以下堆栈invokedynamic 2
:
问题
我的问题是:我该如何使用invokedynamic
?
我无法解析该方法makeConcatWithConstants
,因为 InvokeDynamic-Constant 没有给我任何提示,makeConcatWithConstants
可能位于何处(请参阅文档)。
堆栈也不包含对堆的引用,指示该方法makeConcatWithConstants
可以与哪个实例类型相关联。
我通读了invokedynamic
文档,但我不明白(也许我被 .NET-Framework 严重“损坏”了)。
有人可以给我举一些例子,说明在执行这三个指令时 JVM 引擎盖下发生了什么?(被调用者invokedynamic
期望什么等)?
我已经invokestatic
在我的 JVM 中实现了……但我目前无法理解invokedynamic
。