Skip to content

Commit fee69ba

Browse files
author
Roger Riggs
committedMar 12, 2020
8240704: CheckHandles.java failed "AssertionError: Handle use increased by more than 10 percent."
Reviewed-by: dfuchs
1 parent eeaafbe commit fee69ba

File tree

1 file changed

+73
-34
lines changed

1 file changed

+73
-34
lines changed
 

‎test/jdk/java/lang/ProcessBuilder/checkHandles/CheckHandles.java

+73-34
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
* @test
3232
* @bug 8239893
3333
* @summary Verify that handles for processes that terminate do not accumulate
34-
* @requires (os.family == "windows")
35-
* @run main/native CheckHandles
34+
* @requires ((os.family == "windows") & (vm.compMode != "Xcomp"))
35+
* @run main/othervm/native -Xint CheckHandles
3636
*/
3737
public class CheckHandles {
3838

@@ -43,46 +43,77 @@ public static void main(String[] args) throws Exception {
4343
System.loadLibrary("CheckHandles");
4444

4545
System.out.println("mypid: " + ProcessHandle.current().pid());
46-
long minHandles = Long.MAX_VALUE;
47-
long maxHandles = 0L;
46+
47+
// Warmup the process launch mechanism and vm to stabilize the number of handles in use
48+
int MAX_WARMUP = 20;
49+
long prevCount = getProcessHandleCount();
50+
for (int i = 0; i < MAX_WARMUP; i++) {
51+
oneProcess();
52+
System.gc(); // an opportunity to close unreferenced handles
53+
sleep(10);
54+
55+
long count = getProcessHandleCount();
56+
if (count < 0)
57+
throw new AssertionError("getProcessHandleCount failed");
58+
System.out.println("warmup handle delta: " + (count - prevCount));
59+
prevCount = count;
60+
}
61+
System.out.println("Warmup done");
62+
System.out.println();
63+
64+
prevCount = getProcessHandleCount();
65+
long startHandles = prevCount;
66+
long maxHandles = startHandles;
4867
int MAX_SPAWN = 50;
4968
for (int i = 0; i < MAX_SPAWN; i++) {
50-
try {
51-
Process testProcess = new ProcessBuilder("cmd", "/c", "dir").start();
52-
53-
Thread outputConsumer = new Thread(() -> consumeStream(testProcess.pid(), testProcess.getInputStream()));
54-
outputConsumer.setDaemon(true);
55-
outputConsumer.start();
56-
Thread errorConsumer = new Thread(() -> consumeStream(testProcess.pid(), testProcess.getErrorStream()));
57-
errorConsumer.setDaemon(true);
58-
errorConsumer.start();
59-
60-
testProcess.waitFor();
61-
System.gc();
62-
outputConsumer.join();
63-
errorConsumer.join();
64-
long count = getProcessHandleCount();
65-
if (count < 0)
66-
throw new AssertionError("getProcessHandleCount failed");
67-
minHandles = Math.min(minHandles, count);
68-
maxHandles = Math.max(maxHandles, count);
69-
} catch (IOException | InterruptedException e) {
70-
e.printStackTrace();
71-
throw e;
72-
}
69+
oneProcess();
70+
System.gc(); // an opportunity to close unreferenced handles
71+
sleep(10);
72+
73+
long count = getProcessHandleCount();
74+
if (count < 0)
75+
throw new AssertionError("getProcessHandleCount failed");
76+
System.out.println("handle delta: " + (count - prevCount));
77+
prevCount = count;
78+
maxHandles = Math.max(maxHandles, count);
7379
}
74-
final long ERROR_PERCENT = 10;
75-
final long ERROR_THRESHOLD = // 10% increase over min to passing max
76-
minHandles + ((minHandles + ERROR_PERCENT - 1) / ERROR_PERCENT);
80+
81+
System.out.println("Processes started: " + MAX_SPAWN);
82+
System.out.println("startHandles: " + startHandles);
83+
System.out.println("maxHandles: " + maxHandles);
84+
85+
final float ERROR_PERCENT = 10.0f; // allowable extra handles
86+
final long ERROR_THRESHOLD = startHandles + Math.round(startHandles * ERROR_PERCENT / 100.0f);
7787
if (maxHandles >= ERROR_THRESHOLD) {
78-
System.out.println("Processes started: " + MAX_SPAWN);
79-
System.out.println("minhandles: " + minHandles);
80-
System.out.println("maxhandles: " + maxHandles);
8188
throw new AssertionError("Handle use increased by more than " + ERROR_PERCENT + " percent.");
8289
}
8390
}
8491

85-
private static void consumeStream(long pid, InputStream inputStream) {
92+
/**
93+
* Start a single process and consume its output.
94+
*/
95+
private static void oneProcess() {
96+
try {
97+
98+
Process testProcess = new ProcessBuilder("cmd", "/c", "dir").start();
99+
100+
Thread outputConsumer = new Thread(() -> consumeStream(testProcess.getInputStream()));
101+
outputConsumer.setDaemon(true);
102+
outputConsumer.start();
103+
Thread errorConsumer = new Thread(() -> consumeStream(testProcess.getErrorStream()));
104+
errorConsumer.setDaemon(true);
105+
errorConsumer.start();
106+
107+
testProcess.waitFor();
108+
outputConsumer.join();
109+
errorConsumer.join();
110+
} catch (IOException | InterruptedException e) {
111+
e.printStackTrace();
112+
throw new RuntimeException("Exception", e);
113+
}
114+
}
115+
116+
private static void consumeStream(InputStream inputStream) {
86117
BufferedReader reader = null;
87118
try {
88119
int lines = 0;
@@ -102,4 +133,12 @@ private static void consumeStream(long pid, InputStream inputStream) {
102133
}
103134
}
104135
}
136+
137+
private static void sleep(long millis) {
138+
try {
139+
Thread.sleep(millis);
140+
} catch (InterruptedException ie) {
141+
// ignore
142+
}
143+
}
105144
}

0 commit comments

Comments
 (0)
Please sign in to comment.