14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.BufferedReader;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.lang.ProcessHandle;
29
30 /*
31 * @test
32 * @bug 8239893
33 * @summary Verify that handles for processes that terminate do not accumulate
34 * @requires (os.family == "windows")
35 * @run main/native CheckHandles
36 */
37 public class CheckHandles {
38
39 // Return the current process handle count
40 private static native long getProcessHandleCount();
41
42 public static void main(String[] args) throws Exception {
43 System.loadLibrary("CheckHandles");
44
45 System.out.println("mypid: " + ProcessHandle.current().pid());
46 long minHandles = Long.MAX_VALUE;
47 long maxHandles = 0L;
48 int MAX_SPAWN = 50;
49 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 }
73 }
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);
77 if (maxHandles >= ERROR_THRESHOLD) {
78 System.out.println("Processes started: " + MAX_SPAWN);
79 System.out.println("minhandles: " + minHandles);
80 System.out.println("maxhandles: " + maxHandles);
81 throw new AssertionError("Handle use increased by more than " + ERROR_PERCENT + " percent.");
82 }
83 }
84
85 private static void consumeStream(long pid, InputStream inputStream) {
86 BufferedReader reader = null;
87 try {
88 int lines = 0;
89 reader = new BufferedReader(new InputStreamReader(inputStream));
90 while (reader.readLine() != null) {
91 lines++;
92 }
93 } catch (IOException e) {
94 e.printStackTrace();
95 } finally {
96 if (reader != null) {
97 try {
98 reader.close();
99 } catch (IOException e) {
100 e.printStackTrace();
101 }
102 }
103 }
104 }
105 }
|
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.BufferedReader;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.lang.ProcessHandle;
29
30 /*
31 * @test
32 * @bug 8239893
33 * @summary Verify that handles for processes that terminate do not accumulate
34 * @requires ((os.family == "windows") & (vm.compMode != "Xcomp"))
35 * @run main/othervm/native -Xint CheckHandles
36 */
37 public class CheckHandles {
38
39 // Return the current process handle count
40 private static native long getProcessHandleCount();
41
42 public static void main(String[] args) throws Exception {
43 System.loadLibrary("CheckHandles");
44
45 System.out.println("mypid: " + ProcessHandle.current().pid());
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
54 long count = getProcessHandleCount();
55 if (count < 0)
56 throw new AssertionError("getProcessHandleCount failed");
57 System.out.println("warmup handle delta: " + (count - prevCount));
58 prevCount = count;
59 }
60 System.out.println("Warmup done");
61 System.out.println();
62
63 prevCount = getProcessHandleCount();
64 long startHandles = prevCount;
65 long maxHandles = startHandles;
66 int MAX_SPAWN = 50;
67 for (int i = 0; i < MAX_SPAWN; i++) {
68 oneProcess();
69 System.gc(); // an opportunity to close unreferenced handles
70
71 long count = getProcessHandleCount();
72 if (count < 0)
73 throw new AssertionError("getProcessHandleCount failed");
74 System.out.println("handle delta: " + (count - prevCount));
75 prevCount = count;
76 maxHandles = Math.max(maxHandles, count);
77 }
78
79 System.out.println("Processes started: " + MAX_SPAWN);
80 System.out.println("startHandles: " + startHandles);
81 System.out.println("maxHandles: " + maxHandles);
82
83 final long ERROR_PERCENT = 10;
84 final long ERROR_THRESHOLD = // 10% increase over min to passing max
85 startHandles + ((startHandles + ERROR_PERCENT - 1) / ERROR_PERCENT);
86 if (maxHandles >= ERROR_THRESHOLD) {
87 throw new AssertionError("Handle use increased by more than " + ERROR_PERCENT + " percent.");
88 }
89 }
90
91 /**
92 * Start a single process and consume its output.
93 */
94 private static void oneProcess() {
95 try {
96
97 Process testProcess = new ProcessBuilder("cmd", "/c", "dir").start();
98
99 Thread outputConsumer = new Thread(() -> consumeStream(testProcess.getInputStream()));
100 outputConsumer.setDaemon(true);
101 outputConsumer.start();
102 Thread errorConsumer = new Thread(() -> consumeStream(testProcess.getErrorStream()));
103 errorConsumer.setDaemon(true);
104 errorConsumer.start();
105
106 testProcess.waitFor();
107 outputConsumer.join();
108 errorConsumer.join();
109 } catch (IOException | InterruptedException e) {
110 e.printStackTrace();
111 throw new RuntimeException("Exception", e);
112 }
113 }
114
115 private static void consumeStream(InputStream inputStream) {
116 BufferedReader reader = null;
117 try {
118 int lines = 0;
119 reader = new BufferedReader(new InputStreamReader(inputStream));
120 while (reader.readLine() != null) {
121 lines++;
122 }
123 } catch (IOException e) {
124 e.printStackTrace();
125 } finally {
126 if (reader != null) {
127 try {
128 reader.close();
129 } catch (IOException e) {
130 e.printStackTrace();
131 }
132 }
133 }
134 }
135 }
|