Skip to content

Commit 36b61c5

Browse files
committed
8293872: Make runtime/Thread/ThreadCountLimit.java more robust
Reviewed-by: dholmes, adinn
1 parent 2be3158 commit 36b61c5

File tree

1 file changed

+31
-28
lines changed

1 file changed

+31
-28
lines changed
Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
2525
* @test
2626
* @summary Stress test that reaches the process limit for thread count, or time limit.
2727
* @key stress
28-
* @run main ThreadCountLimit
28+
* @run main/othervm -Xmx1g ThreadCountLimit
2929
*/
3030

3131
import java.util.concurrent.CountDownLatch;
@@ -36,36 +36,18 @@ public class ThreadCountLimit {
3636
static final int TIME_LIMIT_MS = 5000; // Create as many threads as possible in 5 sec
3737

3838
static class Worker extends Thread {
39-
private final int index;
4039
private final CountDownLatch startSignal;
4140

42-
Worker(int index, CountDownLatch startSignal) {
43-
this.index = index;
41+
Worker(CountDownLatch startSignal) {
4442
this.startSignal = startSignal;
4543
}
4644

4745
@Override
4846
public void run() {
49-
if ((index % 250) == 0) {
50-
System.out.println("INFO: thread " + index + " waiting to start");
51-
}
52-
5347
try {
5448
startSignal.await();
5549
} catch (InterruptedException e) {
56-
throw new Error("Unexpected: " + e);
57-
}
58-
59-
setName(String.valueOf(index));
60-
61-
Thread.yield();
62-
63-
if (index != Integer.parseInt(getName())) {
64-
throw new Error("setName/getName failed!");
65-
}
66-
67-
if ((index % 250) == 0) {
68-
System.out.println("INFO: thread " + getName() + " working");
50+
throw new Error("Unexpected", e);
6951
}
7052
}
7153
}
@@ -74,27 +56,37 @@ public static void main(String[] args) {
7456
CountDownLatch startSignal = new CountDownLatch(1);
7557
ArrayList<Worker> workers = new ArrayList<Worker>();
7658

59+
boolean reachedTimeLimit = false;
60+
boolean reachedNativeOOM = false;
61+
int countAtTimeLimit = -1;
62+
int countAtNativeOOM = -1;
63+
64+
// This is dangerous loop: it depletes system resources,
65+
// so doing additional things there that may end up allocating
66+
// Java/native memory risks failing the VM prematurely.
67+
// Avoid doing unnecessary calls, printouts, etc.
68+
7769
int count = 1;
7870
long start = System.currentTimeMillis();
7971
try {
8072
while (true) {
81-
Worker w = new Worker(count, startSignal);
73+
Worker w = new Worker(startSignal);
8274
w.start();
8375
workers.add(w);
8476
count++;
8577

8678
long end = System.currentTimeMillis();
8779
if ((end - start) > TIME_LIMIT_MS) {
88-
// Windows path or a system with very large ulimit
89-
System.out.println("INFO: reached the time limit " + TIME_LIMIT_MS + " ms, with " + count + " threads created");
80+
reachedTimeLimit = true;
81+
countAtTimeLimit = count;
9082
break;
9183
}
9284
}
9385
} catch (OutOfMemoryError e) {
9486
if (e.getMessage().contains("unable to create native thread")) {
9587
// Linux, macOS path
96-
long end = System.currentTimeMillis();
97-
System.out.println("INFO: reached this process thread count limit at " + count + " [" + (end - start) + " ms]");
88+
reachedNativeOOM = true;
89+
countAtNativeOOM = count;
9890
} else {
9991
throw e;
10092
}
@@ -107,7 +99,18 @@ public static void main(String[] args) {
10799
w.join();
108100
}
109101
} catch (InterruptedException e) {
110-
throw new Error("Unexpected: " + e);
102+
throw new Error("Unexpected", e);
103+
}
104+
105+
// Now that all threads have joined, we are away from dangerous
106+
// VM state and have enough memory to perform any other things.
107+
if (reachedTimeLimit) {
108+
// Windows path or a system with very large ulimit
109+
System.out.println("INFO: reached the time limit " + TIME_LIMIT_MS +
110+
" ms, with " + countAtTimeLimit + " threads created");
111+
} else if (reachedNativeOOM) {
112+
System.out.println("INFO: reached this process thread count limit with " +
113+
countAtNativeOOM + " threads created");
111114
}
112115
}
113116
}

0 commit comments

Comments
 (0)