是否收集了lambdas垃圾?

Jav*_*ing 5 java lambda garbage-collection

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

final int local = 123456;
list.forEach(x -> System.out.println(x + local));
Run Code Online (Sandbox Code Playgroud)

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

Raf*_*ter 11

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

不收集上述λ的原因是lambda bootstrap方法优化的结果.通常,bootstrap方法将静态工厂方法绑定到invokedynamic调用站点.如果需要,该工厂将获取封闭方法的所有必需变量以及对声明实例的引用.然后,工厂创建表示lambda的类的实例,并将所有值存储在此实例的字段中.

但是,如果lambda表达式没有任何状态,则bootstrap方法会创建一个单例,然后直接绑定到lambda表达式的调用站点.当然,这个单身人士在封闭课堂之前是无法收集的.

如果你想了解更多关于invokedynamic和lambda表达式如何工作的内容,我最近写了一篇摘要:http://mydailyjava.blogspot.no/2015/03/dismantling-invokedynamic.html?m = 1

这是HotSpot的当前实现,将来可以改变引导程序.


fge*_*fge 6

不,不会; 这不是lambdas的工作方式.

是的,生成了一个类实例; 不,它不会淡出.

lambda是一个使用链接的呼叫站点invokedynamic; 在初始链接完成后,JIT可以自由启动,例如,可以内联代码.所以,你的"类实例"在开始时只是一个真正的类.

例如,如果lambda是方法引用,那么最终JIT会根据此方法引用将lambda内联到invoke {static,virtual,interface,special}.然而,JIT所做的工作依赖于供应商.

  • 因为正如您所描述的那样,JIT 并不真正影响垃圾收集。未收集实例的原因是 lambda 表达式如何引导的结果。这个答案是不正确的。 (2认同)
  • 问题仅仅是关于GC. (2认同)
  • @fge:我认为这篇文章中有许多不清楚或不正确的陈述。“淡出”是什么意思?这是什么意思?:“那么,您的“类实例”实际上只是一开始的类。“类实例”如何成为“类”?“一个 lambda 是一个调用站点”是什么意思? (2认同)