Java 可完成的未来和垃圾收集
我想启动许多一次性异步CompletableFutures,如下所示: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
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的引用。或者简言之,垃圾收集器不会更改程序的语义;不管完成是如何实现的,因为它是以一种它将发生的方式实现的,因此它将发生,垃圾收集器不会改变这一点。