gpt4 book ai didi

java - OpenJDK 8 Lambdas 处理

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:49:41 26 4
gpt4 key购买 nike

在我当前的项目中,我希望能够“重新实例化”一个 lambda 方法(虽然不知道“重新实例化”是否是正确的词)

考虑下面的例子

public static void main(String[] args) throws Throwable {
TestUser tu = new TestUser();

ITest1 lam = t->{
System.out.println("whoops" + tu.toString());
return 1;
};

tu.doExec(lam);

calls++;
if( calls == 1) main(args);
}

在这里,我尝试通过 JVM 调用进行调试,我注意到 JVM 为元工厂方法创建了 MethodTypeMethodHandle 对象(它创建构建 CallSite ) 和我的 lambda 方法。现在一旦完成,就会调用 linkCallSite。此方法构建 CallSite 并将 lambda 方法链接到它一次。此时,我的问题是,我能否以某种方式从 jvm 中删除 lambda CallSite 和 LambdaForm 并以某种方式再次触发整个过程?

还有一个问题,当通过 JVM 调用进行调试时,我注意到每次 JVM 执行 lambda 方法时,一个方法 Ljava/lang/invoke/LambdaForm$MH/818403870;.linkToTargetMethod(Object) 被调用,我找不到它的源代码,无论是在 JVM cpp 源中,还是在 java 中。这个方法究竟是如何调用的,或者它在哪里被调用?

我知道这个问题有点复杂,所以我愿意回答您的问题。提前谢谢你。

最佳答案

can I somehow delete the lambda CallSite and LambdaForm from the jvm and somehow trigger the whole process again?

invokedynamic 在字节码解析时间仅链接到 CallSite(或有时直接链接到目标方法)一次。解析结果保存在常量池缓存中,以后不修改。

重置常量池缓存的一种可能方法是重新定义类。我不计算在不同的 ClassLoader 中重新加载类,因为这在技术上等同于加载与旧类无关的新类。

因此,为了再次触发 linkCallSite 内容,您可以调用 Instrumentation.redefineClasses或等效的 JVM TI RedefineClasses功能。

How exactly is this method called, or where does it get invoked?

linkToTargetMethod 是一个在运行时动态创建的适配器,用于调用链接到特定 invokedynamic 字节码的 MethodHandle。它基本上是调用此适配器的 invokedynamic 的实现。

Here is生成此适配器的源。

关于java - OpenJDK 8 Lambdas 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45760558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com