Java 垃圾收集和异步调用/未来对象

Java 垃圾收集和异步调用/未来对象,java,multithreading,Java,Multithreading,下面是利用Future接口进行异步调用的示例代码。我需要一些关于get()方法的说明 Future-Future=getAsyncString(); //做点什么。。。 字符串msg=“”; 如果(验证) 返回; 其他的 msg=future.get(); //做点别的。。。 返回; future变量在方法中初始化,因此该变量将在方法执行后很快被GC清除,因为它不再使用。 那么,如果代码进入if语句,JVM的状态会是什么?JVM将如何处理包装后的结果,以防无人将其读回?它会影响线程池还是线程执

下面是利用Future接口进行异步调用的示例代码。我需要一些关于get()方法的说明

Future-Future=getAsyncString();
//做点什么。。。
字符串msg=“”;
如果(验证)
返回;
其他的
msg=future.get();
//做点别的。。。
返回;
future变量在方法中初始化,因此该变量将在方法执行后很快被GC清除,因为它不再使用。 那么,如果代码进入if语句,JVM的状态会是什么?JVM将如何处理包装后的结果,以防无人将其读回?它会影响线程池还是线程执行器

JVM将如何处理包装后的结果,以防无人将其读回

大概您是从
执行器
获得了
未来
对象。为了使此执行器能够在
未来
中设置结果,它保留了对
未来
的引用。换句话说,仅仅因为对象的方法本地引用在调用堆栈弹出时消失,并不意味着
Future
对象(位于堆上)自动符合垃圾收集的条件

异步调用没有被取消或类似的操作。执行器将执行调用,填写结果,并可能删除它对
未来
对象的引用。此时,对象变得不可访问,并且符合垃圾收集的条件

如果您确定您的代码没有保留对
Future
对象的引用(即在
//do something…
部分泄漏),那么您可以确保
Future
对象(最终)由GC收集。(执行器在这里没有任何细微的内存泄漏。)

[…]因此该变量很快将被GC清除

确切地说,当调用堆栈弹出时,变量将被丢弃。这最终将导致
未来的
对象无法访问,并且有资格进行垃圾收集。然而,对象通常不会在方法返回时立即被垃圾收集

JVM将如何处理包装后的结果,以防无人将其读回


如果没有人(我指的是任何程序)读回它,那么GC将在垃圾收集期间处理它。但这并不意味着
getAsyncString()
不会完全执行,相反,它会像正常方法一样正常完成。

您可以保证,当您在定义对象引用的范围内,或者在代码中的某个地方存在对对象的引用时,不会对该对象进行GCed

这适用于所有对象,未来在这里没有区别


因此,一旦您的方法结束,并且其调用堆栈被清除,在将来的某个时候,您的对象将有资格进行垃圾收集,但肯定不会在方法的调用堆栈上存在对它的引用之前进行垃圾收集。

我猜。在任务完成之前,计划的未来将有一些来自线程池队列的内部引用。因此,在任务完成之前,gc无法收集这些数据


可能在future和executor之间存在额外的抽象级别,可以收集future。但我相信,若任务提交,它将运行。不管是不是保存了指向未来的指针

GC不会清除变量。GC将清除不再被任何变量引用的对象。请注意,变量不是对象;变量是对对象的引用。是的,代码表明未来的实例将仅在方法中使用。为什么要在
getAsyncString()
之后而不是之前进行验证?这就是我要确认的答案,我们如何确认它?我应该在运行时检查mem空间吗?您想确认什么,它是垃圾收集的还是执行完成的?不,它肯定会执行,因为调用方法时,问题是如果代码永远不会到达未来,包装的结果会发生什么。get()?它会产生内存泄漏还是什么?不会,它不会产生内存泄漏,因为执行是由executor处理的,所以即使您不调用get方法,executor也会确保您的方法被执行。如果将来的对象不是从其他地方引用的,它将由GC处理,就像处理普通变量一样。好的,这就是我想确认的,因为我在任何oracle/java文档中都找不到它,感谢您的帮助和时间,您建议在方法执行后,即使我没有调用future.get(),对包装结果的引用仍然存在,因为线程执行器持有变量?@AntJavaDev future正在执行的方法不会被中断。它将完成,此时执行器将释放其引用,Future对象将有资格进行垃圾收集。@Quilliom,请注意,
Future
应该为其捕获结果的方法可能尚未调用。(例如,假设一个线程池中有一个线程,队列中有许多任务。)因此,即使将来的.get()方法从未被调用,它也有资格进行垃圾收集?@AntJavaDev,是的,但可能在执行底层异步调用之前是这样(因为在此之前,执行者将保留对
未来的引用
,因此它知道将结果放在何处)。
Future<String> future = getAsyncString();
//do something ...
String msg = "";
if (validation)
    return;
else
    msg = future.get();
//do something else...
return;