Java 可完成的未来和垃圾收集

Java 可完成的未来和垃圾收集,java,asynchronous,garbage-collection,completable-future,Java,Asynchronous,Garbage Collection,Completable Future,我想启动许多一次性异步CompletableFutures,如下所示: for (Job job : jobs) { CompletableFuture.supplyAsync(() -> job.process()) .whenComplete(this::doSomething); } 理想情况下,这些可完成的未来可以在完成后进行垃圾收集。但是,由于我没有存储引用,是否存在事先收集的风险?您没有明确存储引用,但是supplyAsync是内部存储的。该方法创建一个Complet

我想启动许多一次性异步CompletableFutures,如下所示:

for (Job job : jobs) {
 CompletableFuture.supplyAsync(() -> job.process())
   .whenComplete(this::doSomething);
}

理想情况下,这些可完成的未来可以在完成后
进行垃圾收集。但是,由于我没有存储引用,是否存在事先收集的风险?

您没有明确存储引用,但是
supplyAsync
是内部存储的。该方法创建一个
CompletableFuture
,并将一个任务提交给
ForkJoinPool
(如果您使用的是公共池),该池有一个对它的引用。当complete
依赖于第一个
CompletableFuture
时,由
返回的
CompletableFuture
也被引用

一旦
ForkJoinPool
完成
Supplier
的执行,将第一个
CompletableFuture
标记为complete,触发第二个
CompletableFuture
,并在完成时执行传递给
BiConsumer
,所有这些对象都将可用于垃圾收集


您是安全的。

在标记阶段,所有可从Java线程、本机句柄和其他根源访问的对象以及可从这些对象访问的对象等都标记为活动对象。这个过程识别并标记所有仍在使用的对象,其余的可以被视为垃圾。我检查了
supplyAsync
的源代码,可以确认提交给执行器的AsyncSupply runnable保存了对CompletableFuture的引用。或者简言之,垃圾收集器不会更改程序的语义;不管完成是如何实现的,因为它是以一种它将发生的方式实现的,因此它将发生,垃圾收集器不会改变这一点。