Lambda表达式匿名对象生命周期

时间:2014-11-01 07:01:39

标签: java object lambda garbage-collection lifecycle

我的问题是关于JVM 1.8中匿名对象的处理和生命周期。

据我所知,在JDK 1.8中,lambda表达式的基本机制并不是纯粹基于函数的。即它仍然使用我们在代码中定义的方法创建一个匿名对象,并在匿名对象上调用该方法。另外,因为lambda表达式没有引入任何新的变量范围,所以调用"这个"在lambda表达式中,它将引用原始对象而不是这种匿名方法。

自然,问题如下:JVM如何处理这种匿名对象的生命周期?将包含这样的lambda表达式的对象方法定义为"外部对象方法",至少我有以下问题。

  1. 如果外部对象方法是普通方法,这个匿名对象是属于实例级别还是类级别?如果外部方法是静态的,该怎么办?

  2. 如果多次调用外部对象方法,是否会重新使用或重新创建此匿名对象?

  3. 此类对象是否受JVM GC约束?如果是,GC规则与其他对象保持一致吗?

  4. 是否有任何工具或API来跟踪此类匿名对象的生命周期,因为它无法直接在代码中引用?

  5. 感谢任何帮助,评论或文档。

1 个答案:

答案 0 :(得分:0)

  1. 我不知道你的意思是什么"属于"。一个对象不属于"任何级别。

  2. 如果lambda是一个闭包,即它从周围范围捕获一个或多个局部变量(包括this(有点像隐式final局部变量),{ {1}}(通过OuterClass.this隐藏字段隐式访问)或非限定实例变量(通过thisthis隐式访问)),然后在不同时间评估包含lambda表达式的函数,它可能必须创建不同的对象,因为捕获的变量的值存储为lambda对象的一部分,并且因为在函数的不同运行中(或者甚至在一次运行中的不同时间)在函数中,捕获的变量可以有不同的值,必须创建不同的lambda对象,以便每个lambda记住它独立的捕获值集。

    但是,如果lambda不是闭包,那么从该lambda表达式创建的任何两个lambda对象在语义上都是不可区分的。因此,可以将一个对象重用于该lambda表达式的所有求值。我相信在这种情况下,虚拟机将为该lambda静态分配一个对象,该对象在程序的持续时间内存在。

  3. 是。如果在运行lambda表达式时创建了一个对象,那么它将像Java中的其他对象一样动态分配,并且它受GC的影响。但是,如果在程序的整个生命周期中创建了一个对象(参见上面(2)的讨论),那么它就不会受内存管理,类似于字符串文字。