jdk/test/java/lang/ProcessBuilder/BigFork.java
author ohair
Tue, 25 May 2010 15:58:33 -0700
changeset 5506 202f599c92aa
parent 2946 f95752c3204a
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     1
/*
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     2
 * Copyright 2009 Google Inc.  All Rights Reserved.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     4
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     7
 * published by the Free Software Foundation.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     8
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    13
 * accompanied this code).
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    14
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    18
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2946
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2946
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2946
diff changeset
    21
 * questions.
2946
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    22
 */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    23
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    24
import java.util.*;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    25
import java.io.*;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    26
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    27
/**
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    28
 * A manual test that demonstrates the ability to start a subprocess
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    29
 * on Linux without getting ENOMEM.  Run this test like:
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    30
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    31
 * java -Xmx7000m BigFork
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    32
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    33
 * providing a -Xmx flag suitable for your operating environment.
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    34
 * Here's the bad old behavior:
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    35
 *
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    36
 * ==> java -Xmx7000m -esa -ea BigFork
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    37
 * -------
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    38
 * CommitLimit:   6214700 kB
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    39
 * Committed_AS:  2484452 kB
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    40
 * -------
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    41
 * size=4.6GB
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    42
 * -------
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    43
 * CommitLimit:   6214700 kB
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    44
 * Committed_AS:  7219680 kB
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    45
 * -------
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    46
 * Exception in thread "main" java.io.IOException: Cannot run program "/bin/true": java.io.IOException: error=12, Cannot allocate memory
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    47
 *         at java.lang.ProcessBuilder.start(ProcessBuilder.java:1018)
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    48
 *         at BigFork.main(BigFork.java:79)
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    49
 * Caused by: java.io.IOException: java.io.IOException: error=12, Cannot allocate memory
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    50
 *         at java.lang.UNIXProcess.<init>(UNIXProcess.java:190)
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    51
 *         at java.lang.ProcessImpl.start(ProcessImpl.java:128)
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    52
 *         at java.lang.ProcessBuilder.start(ProcessBuilder.java:1010)
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    53
 *         ... 1 more
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    54
 */
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    55
public class BigFork {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    56
    static final Random rnd = new Random();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    57
    static void touchPages(byte[] chunk) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    58
        final int pageSize = 4096;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    59
        for (int i = 0; i < chunk.length; i+= pageSize) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    60
            chunk[i] = (byte) rnd.nextInt();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    61
        }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    62
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    63
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    64
    static void showCommittedMemory() throws IOException {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    65
        BufferedReader r =
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    66
            new BufferedReader(
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    67
                new InputStreamReader(
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    68
                    new FileInputStream("/proc/meminfo")));
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    69
        System.out.println("-------");
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    70
        String line;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    71
        while ((line = r.readLine()) != null) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    72
            if (line.startsWith("Commit")) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    73
                System.out.printf("%s%n", line);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    74
            }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    75
        }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    76
        System.out.println("-------");
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    77
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    78
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    79
    public static void main(String[] args) throws Throwable {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    80
        showCommittedMemory();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    81
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    82
        final int chunkSize = 1024 * 1024 * 100;
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    83
        List<byte[]> chunks = new ArrayList<byte[]>(100);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    84
        try {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    85
            for (;;) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    86
                byte[] chunk = new byte[chunkSize];
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    87
                touchPages(chunk);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    88
                chunks.add(chunk);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    89
            }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    90
        } catch (OutOfMemoryError e) {
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    91
            chunks.set(0, null);        // Free up one chunk
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    92
            System.gc();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    93
            int size = chunks.size();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    94
            System.out.printf("size=%.2gGB%n", (double)size/10);
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    95
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    96
            showCommittedMemory();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    97
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    98
            // Can we fork/exec in our current bloated state?
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
    99
            Process p = new ProcessBuilder("/bin/true").start();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
   100
            p.waitFor();
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
   101
        }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
   102
    }
f95752c3204a 6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
diff changeset
   103
}