这里的数据变量什么时候可以进行垃圾回收?以及JVM如何知道这个数据变量必须是活的,因为我的任务是活的。我的编辑唯一说的是变量需要是final或有效的final。好吧,我不会更新它,但仍然将如何参考结转?java也有类似JavaScript的闭包的概念吗?或者它是什么进程?我要求任何官方的JVM规范文档或任何可信的来源,我可以得到关于在这种情况下到底发生了什么的信息。
public void schedule() {
String data = "adfasdf";
scheduler.newJob("bussinessruleid")
.setCron("0/5 * * * * ?")
.setTask(executionContext -> {
System.out.println(executionContext + " " + data);
}).schedule();
}
字符串
1条答案
按热度按时间gg0vcinb1#
只要
scheduler.newJob()
调度的任务处于活动状态,data
变量就会保持活动状态,因为任务的回调函数会捕获数据,防止其被垃圾收集。你可以把例子中的数据变量看作是你提供给
setTask()
的匿名函数“捕获”的。这里,“捕获”意味着即使在schedule()返回之后,函数也保留对数据的引用。只要函数本身是活动的,匿名函数就保持数据变量是活动的。在您的例子中,只要您创建的计划任务仍然存在,数据就没有资格进行垃圾收集,因为它仍然被引用。
JVM知道保持数据的活动性,因为它看到函数已经捕获了数据,因此维护了对它的引用。这不是Java独有的;这是许多支持闭包的编程语言中的一个常见特性。
当代码运行
schedule()
时,该方法将完成,在正常情况下,当该方法返回时,像数据这样的局部变量将有资格进行垃圾收集。但是由于匿名函数捕获数据,并且函数本身由调度程序保持活动状态,因此JVM知道将数据保存在内存中。"final"
意味着变量的值在赋值后不能改变。它本质上与final相同,但没有显式的final修饰符。Java 8中引入它是为了在使用lambda表达式和匿名类时给予更大的灵活性,匿名类只能从外部作用域访问final或有效的final变量。