2626 * @summary Stress test that reaches the process limit for thread count, or time limit.
2727 * @requires os.family != "aix"
2828 * @key stress
29+ * @library /test/lib
2930 * @run main/othervm -Xmx1g ThreadCountLimit
3031 */
3132
3435 * @summary Stress test that reaches the process limit for thread count, or time limit.
3536 * @requires os.family == "aix"
3637 * @key stress
38+ * @library /test/lib
3739 * @run main/othervm -Xmx1g -XX:MaxExpectedDataSegmentSize=16g ThreadCountLimit
3840 */
3941
4042import java .util .concurrent .CountDownLatch ;
4143import java .util .ArrayList ;
4244
45+ import jdk .test .lib .Platform ;
46+ import jdk .test .lib .process .OutputAnalyzer ;
47+ import jdk .test .lib .process .ProcessTools ;
48+
4349public class ThreadCountLimit {
4450
4551 static final int TIME_LIMIT_MS = 5000 ; // Create as many threads as possible in 5 sec
@@ -61,21 +67,42 @@ public void run() {
6167 }
6268 }
6369
64- public static void main (String [] args ) {
70+ public static void main (String [] args ) throws Exception {
71+ if (args .length == 0 ) {
72+ // Called from the driver process so exec a new JVM on Linux.
73+ if (Platform .isLinux ()) {
74+ // On Linux this test sometimes hits the limit for the maximum number of memory mappings,
75+ // which leads to various other failure modes. Run this test with a limit on how many
76+ // threads the process is allowed to create, so we hit that limit first.
77+
78+ final String ULIMIT_CMD = "ulimit -u 4096" ;
79+ ProcessBuilder pb = ProcessTools .createTestJavaProcessBuilder (ThreadCountLimit .class .getName ());
80+ String javaCmd = ProcessTools .getCommandLine (pb );
81+ // Relaunch the test with args.length > 0, and the ulimit set
82+ ProcessTools .executeCommand ("bash" , "-c" , ULIMIT_CMD + " && " + javaCmd + " dummy" )
83+ .shouldHaveExitValue (0 );
84+ } else {
85+ // Not Linux so run directly.
86+ test ();
87+ }
88+ } else {
89+ // This is the exec'd process so run directly.
90+ test ();
91+ }
92+ }
93+
94+ static void test () {
6595 CountDownLatch startSignal = new CountDownLatch (1 );
6696 ArrayList <Worker > workers = new ArrayList <Worker >();
6797
68- boolean reachedTimeLimit = false ;
6998 boolean reachedNativeOOM = false ;
70- int countAtTimeLimit = -1 ;
71- int countAtNativeOOM = -1 ;
7299
73100 // This is dangerous loop: it depletes system resources,
74101 // so doing additional things there that may end up allocating
75102 // Java/native memory risks failing the VM prematurely.
76103 // Avoid doing unnecessary calls, printouts, etc.
77104
78- int count = 1 ;
105+ int count = 0 ;
79106 long start = System .currentTimeMillis ();
80107 try {
81108 while (true ) {
@@ -86,16 +113,15 @@ public static void main(String[] args) {
86113
87114 long end = System .currentTimeMillis ();
88115 if ((end - start ) > TIME_LIMIT_MS ) {
89- reachedTimeLimit = true ;
90- countAtTimeLimit = count ;
116+ // Windows always gets here, but we also get here if
117+ // ulimit is set high enough.
91118 break ;
92119 }
93120 }
94121 } catch (OutOfMemoryError e ) {
95122 if (e .getMessage ().contains ("unable to create native thread" )) {
96- // Linux, macOS path
123+ // Linux, macOS path if we hit ulimit
97124 reachedNativeOOM = true ;
98- countAtNativeOOM = count ;
99125 } else {
100126 throw e ;
101127 }
@@ -113,13 +139,12 @@ public static void main(String[] args) {
113139
114140 // Now that all threads have joined, we are away from dangerous
115141 // VM state and have enough memory to perform any other things.
116- if (reachedTimeLimit ) {
117- // Windows path or a system with very large ulimit
118- System .out .println ("INFO: reached the time limit " + TIME_LIMIT_MS +
119- " ms, with " + countAtTimeLimit + " threads created" );
120- } else if (reachedNativeOOM ) {
121- System .out .println ("INFO: reached this process thread count limit with " +
122- countAtNativeOOM + " threads created" );
142+ if (reachedNativeOOM ) {
143+ System .out .println ("INFO: reached this process thread count limit with " +
144+ count + " threads created" );
145+ } else {
146+ System .out .println ("INFO: reached the time limit " + TIME_LIMIT_MS +
147+ " ms, with " + count + " threads created" );
123148 }
124149 }
125150}
0 commit comments