このコードでは、これらの先物のガベージコレクションを妨げるものは何もないため、必要はありません。問題のこのコードは、最初のCompletableFuture
(this
インスタンス)が完了し、直接評価された作成機能によって返されたCompletableFuture
がまだ完了していないシナリオに適用されます。
は今、2つのシナリオは、現在進行中の完了の試みがあり
があります。最終的に未来を完成させるコードはそれへの参照を保持し、完了すると、依存する段階の完了を引き起こすでしょう(g.push(copy)
を介して登録されています)。このシナリオでは、従属ステージがその前提ステージへの参照を保持する必要はありません。
これは一般的なパターンです。 x --will complete-→ y
のチェーンがある場合、y
からx
への参照はありません。
CompletableFuture
インスタンスg
とg
はまだ完了していません。この場合、決して完了することはなく、g
への参照を内部的に保持してもそれは変わりません。それは資源を浪費するだけです。
次のプログラム例は、この説明します:thenCompose
に渡された最初の関数が作成し、それを完了しようとせずに、新しい未完了CompletableFuture
を返す、と他の参照を保持しても保存しない
public static void main(String[] args) throws Throwable {
ReferenceQueue<Object> discovered = new ReferenceQueue<>();
Set<WeakReference<?>> holder = new HashSet<>();
CompletableFuture<Object> initial = CompletableFuture.completedFuture("somevalue");
CompletableFuture<Object> finalStage = initial.thenCompose(value -> {
CompletableFuture<Object> lost = new CompletableFuture<>();
holder.add(new WeakReference<>(lost, discovered));
return lost;
});
waitFor(finalStage, holder, discovered);
finalStage = initial.thenCompose(value -> {
CompletableFuture<Object> saved = CompletableFuture.supplyAsync(()-> {
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
return "newvalue";
});
holder.add(new WeakReference<>(saved, discovered));
return saved;
});
waitFor(finalStage, holder, discovered);
}
private static void waitFor(CompletableFuture<Object> f, Set<WeakReference<?>> holder,
ReferenceQueue<Object> discovered) throws InterruptedException {
while(!f.isDone() && !holder.isEmpty()) {
System.gc();
Reference<?> removed = discovered.remove(100);
if(removed != null) {
holder.remove(removed);
System.out.println("future has been garbage collected");
}
}
if(f.isDone()) {
System.out.println("stage completed with "+f.join());
holder.clear();
}
}
をそれ。対照的に、2番目の関数は、でCompletableFuture
を作成し、Supplier
を提供し、1秒後に値を返します。私のシステムで
、それは一貫して、他の少なくとも完了するまで保持されている間に放棄将来ガベージコレクションを防止することがないことを示す
future has been garbage collected
stage completed with newvalue
プリント。
私はtryFireコールを見逃しましたが、内部で何が起こっているのかまだわかりません(コードは読みにくいです)ので、回答はまだ高く評価されています。 – Etki
参照はGC'edヒープダンプを見てください。 – NickL