我对java 8的'封闭'有些困惑。据说它会关闭价值观。 考虑以下课程。
public class SomeClassWithLargeMemoryFootprint {
//some state
private SomeObject someObj;
//some more state
public void doSomething(SomeAsyncHelper helper) {
helper.doAsync( () -> {
//some super slow operation
int foo = someObj.whatever();
//some more stuff
});
}
}
//Let's assume SomeAsyncHelper.doAsync takes a VoidRunner that looks like below
interface VoidRunner {
void apply();
}
问题是,当异步帮助程序仍在工作时,SomeClassWithLargeMemoryFootprint的实例是否可以GC? 我很清楚“someObj”不能是GC,因为doSomething()中的lambda需要它。那个州的其他地方怎么样?
另外,请考虑以下变量,我们调用包含类的成员方法:
public class SomeClassWithLargeMemoryFootprint {
//some state
private SomeObject someObj;
//some more state
public void doSomething(SomeAsyncHelper helper) {
helper.doAsync( () -> {
//do something
memberMethod();
//do something else
});
}
private void memberMethod() {
//do something
}
}
现在怎么样? '助手'如何知道如何执行“memberMethod”?它是否获得对SomeClassWithLargeMemoryFootprint实例的引用? GC序列是什么?
答案 0 :(得分:2)
当异步帮助程序仍在工作时,SomeClassWithLargeMemoryFootprint的实例是否可以GC?
没有。 VoidRunner实例对其封闭的SomeClassWithLargeMemoryFootprint对象有强引用,并且它本身由异步任务执行程序引用。所以它不能被GCed。
其他州呢?
状态的其余部分由SomeClassWithLargeMemoryFootprint的实例引用,因此无法进行GCed。
'助手'如何知道如何执行“memberMethod”
它在第一个示例中知道如何访问this.someObj
(即this
)的方式相同:它包含对其封闭的SomeClassWithLargeMemoryFootprint对象的引用(即let routes = []
app._router.stack.forEach(function (middleware) {
if(middleware.route) {
routes.push(Object.keys(middleware.route.methods) + " -> " + middleware.route.path);
}
});
console.log(JSON.stringify(routes, null, 4));
)。