-
Bug
-
Resolution: Fixed
-
P3
-
None
-
b129
CompletableFuture.anyOf attaches Completion objects to its input CompletableFutures. Those Completion objects are not removed from incomplete source futures if the anyOf triggers due to completion of one of its inputs, and so become garbage. If the input futures are long lived and never completed (which is unusual!), we have a memory leak.
In jsr166 CVS, you can run:
$ cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
...
1) testAnyOfGarbageRetention(CompletableFutureTest)java.lang.OutOfMemoryError: Java heap space
/**
* Reproduction recipe for:
* 8160402: Garbage retention with CompletableFuture.anyOf
* cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
*/
public void testAnyOfGarbageRetention() throws Throwable {
for (Integer v : new Integer[] { 1, null })
{
final int n = expensiveTests ? 100_000 : 10;
CompletableFuture<Integer>[] fs
= (CompletableFuture<Integer>[]) new CompletableFuture<?>[100];
for (int i = 0; i < fs.length; i++)
fs[i] = new CompletableFuture<>();
fs[fs.length - 1].complete(v);
for (int i = 0; i < n; i++)
checkCompletedNormally(CompletableFuture.anyOf(fs), v);
}}
In jsr166 CVS, you can run:
$ cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
...
1) testAnyOfGarbageRetention(CompletableFutureTest)java.lang.OutOfMemoryError: Java heap space
/**
* Reproduction recipe for:
* 8160402: Garbage retention with CompletableFuture.anyOf
* cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
*/
public void testAnyOfGarbageRetention() throws Throwable {
for (Integer v : new Integer[] { 1, null })
{
final int n = expensiveTests ? 100_000 : 10;
CompletableFuture<Integer>[] fs
= (CompletableFuture<Integer>[]) new CompletableFuture<?>[100];
for (int i = 0; i < fs.length; i++)
fs[i] = new CompletableFuture<>();
fs[fs.length - 1].complete(v);
for (int i = 0; i < n; i++)
checkCompletedNormally(CompletableFuture.anyOf(fs), v);
}}