Java 兰姆达斯垃圾收集了吗?

Java 兰姆达斯垃圾收集了吗?,java,lambda,garbage-collection,Java,Lambda,Garbage Collection,如果我没有弄错的话,在某些情况下,Java中的lambda是作为匿名类实例生成的。例如,在此代码中,lambda需要从外部捕获一个变量: final int local = 123456; list.forEach(x -> System.out.println(x + local)); 这是否意味着垃圾收集器将声明lambda为对象?不,它不会;这不是lambda的工作方式 是,生成一个类实例;不,不会褪色的 lambda是使用invokedynamic链接的调用站点;初始链接完成后,

如果我没有弄错的话,在某些情况下,Java中的lambda是作为匿名类实例生成的。例如,在此代码中,lambda需要从外部捕获一个变量:

final int local = 123456;
list.forEach(x -> System.out.println(x + local));

这是否意味着垃圾收集器将声明lambda为对象?

不,它不会;这不是lambda的工作方式

是,生成一个类实例;不,不会褪色的

lambda是使用
invokedynamic
链接的调用站点;初始链接完成后,JIT可以自由启动,例如,可以内联代码。因此,您的“类实例”实际上只是一个刚开始的类


例如,如果lambda是一个方法引用,那么JIT最终将根据该方法引用的内容将lambda内联到调用{static,virtual,interface,special}中。但是,JIT所做的工作取决于供应商。

是的,表示lambda表达式的实例与任何其他对象一样被垃圾收集。如果包含lambda表达式的类符合收集条件,则甚至可以收集实现函数接口的类

未收集上述lambda的原因是通过lambda引导方法进行优化的结果。通常,引导方法将静态工厂方法绑定到InvokedDynamic调用站点。该工厂获取封闭方法的所有必需变量和对声明实例的引用(如果需要)。然后,工厂创建一个表示lambda的类实例,并将所有值存储在此实例的字段中

但是,如果lambda表达式没有任何状态,则引导方法将创建一个单例,然后直接绑定到lambda表达式的调用站点。当然,在创建封闭类之前,无法收集此单例

如果您想进一步了解InvokedDynamic和lambda表达式的工作原理,我最近写了一篇总结:


这是HotSpot的当前实现,引导程序将来可能会更改。

这-1来自哪里?是的,我想知道。你的回答很可靠,所以我认为它是有效的。谢谢。因为JIT并没有像您描述的那样真正影响垃圾收集。未收集实例的原因是lambda表达式如何引导的结果。这个答案是不正确的。这个问题仅仅是关于GC的。@fge:我认为这篇文章中有一些不清楚或不正确的陈述。“淡出”是什么意思?这意味着什么?:“那么,你的“类实例”实际上只是一个刚开始的类。“类实例”怎么可能是一个“类”?“lambda是呼叫站点”是什么意思?