jdk/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java
author alanb
Thu, 17 Mar 2016 19:04:16 +0000
changeset 36511 9d0388c6b336
parent 25859 3317bb8137f4
child 38360 fb63be22ffa6
permissions -rw-r--r--
8142968: Module System implementation Summary: Initial integration of JEP 200, JEP 260, JEP 261, and JEP 282 Reviewed-by: alanb, mchung, naoto, rriggs, psandoz, plevart, mullan, ascarpino, vinnie, prr, sherman, dfuchs, mhaupt Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, chris.hegarty@oracle.com, alexandr.scherbatiy@oracle.com, amy.lu@oracle.com, calvin.cheung@oracle.com, daniel.fuchs@oracle.com, erik.joelsson@oracle.com, harold.seigel@oracle.com, jaroslav.bachorik@oracle.com, jean-francois.denise@oracle.com, jan.lahoda@oracle.com, james.laskey@oracle.com, lois.foltan@oracle.com, miroslav.kos@oracle.com, huaming.li@oracle.com, sean.mullan@oracle.com, naoto.sato@oracle.com, masayoshi.okutsu@oracle.com, peter.levart@gmail.com, philip.race@oracle.com, claes.redestad@oracle.com, sergey.bylokhov@oracle.com, alexandre.iline@oracle.com, volker.simonis@gmail.com, staffan.larsen@oracle.com, stuart.marks@oracle.com, semyon.sadetsky@oracle.com, serguei.spitsyn@oracle.com, sundararajan.athijegannathan@oracle.com, valerie.peng@oracle.com, vincent.x.ryan@oracle.com, weijun.wang@oracle.com, yuri.nesterenko@oracle.com, yekaterina.kantserova@oracle.com, alexander.kulyakhtin@oracle.com, felix.yang@oracle.com, andrei.eremeev@oracle.com, frank.yuan@oracle.com, sergei.pikalev@oracle.com, sibabrata.sahoo@oracle.com, tiantian.du@oracle.com, sha.jiang@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
16501
678abe06c15c 8005116: NPG: Rename -permstat option for jmap in jdk8 to -clstats
stefank
parents: 14342
diff changeset
     2
 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1247
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.tools.jmap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import com.sun.tools.attach.VirtualMachine;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import com.sun.tools.attach.AttachNotSupportedException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import sun.tools.attach.HotSpotVirtualMachine;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
    35
import jdk.internal.vm.agent.spi.ToolProvider;
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
    36
import jdk.internal.vm.agent.spi.ToolProviderFinder;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * This class is the main class for the JMap utility. It parses its arguments
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 16501
diff changeset
    40
 * and decides if the command should be satisfied using the VM attach mechanism
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * or an SA tool. At this time the only option that uses the VM attach mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * is the -dump option to get a heap dump of a running application. All other
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * options are mapped to SA tools.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
public class JMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    // Options handled by the attach mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    private static String HISTO_OPTION = "-histo";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private static String LIVE_HISTO_OPTION = "-histo:live";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    private static String DUMP_OPTION_PREFIX = "-dump:";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // These options imply the use of a SA tool
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    private static String SA_TOOL_OPTIONS =
16501
678abe06c15c 8005116: NPG: Rename -permstat option for jmap in jdk8 to -clstats
stefank
parents: 14342
diff changeset
    54
      "-heap|-heap:format=b|-clstats|-finalizerinfo";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    // The -F (force) option is currently not passed through to SA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static String FORCE_SA_OPTION = "-F";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    // Default option (if nothing provided)
1089
12e2f9ad0367 6653883: jmap with no option should print mmap instead of heap information.
swamyv
parents: 2
diff changeset
    60
    private static String DEFAULT_OPTION = "-pmap";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    public static void main(String[] args) throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        if (args.length == 0) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
    64
            usage(1); // no arguments
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
        // used to indicate if we should use SA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        boolean useSA = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        // the chosen option (-heap, -dump:*, ... )
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        String option = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        // First iterate over the options (arguments starting with -).  There should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        // one (but maybe two if -F is also used).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        int optionCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        while (optionCount < args.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            String arg = args[optionCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            if (!arg.startsWith("-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
            }
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
    81
            if (arg.equals("-help") || arg.equals("-h")) {
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
    82
                usage(0);
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
    83
            } else if (arg.equals(FORCE_SA_OPTION)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
                useSA = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
                if (option != null) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
    87
                    usage(1);  // option already specified
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                option = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            optionCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        // if no option provided then use default.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        if (option == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            option = DEFAULT_OPTION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        if (option.matches(SA_TOOL_OPTIONS)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            useSA = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        // Next we check the parameter count. For the SA tools there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        // one or two parameters. For the built-in -dump option there is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        // only one parameter (the process-id)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        int paramCount = args.length - optionCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        if (paramCount == 0 || paramCount > 2) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   107
            usage(1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        if (optionCount == 0 || paramCount != 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            useSA = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            // the parameter for the -dump option is a process-id.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
            // If it doesn't parse to a number then it must be SA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            // debug server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            if (!args[optionCount].matches("[0-9]+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                useSA = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        // at this point we know if we are executing an SA tool or a built-in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        // option.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        if (useSA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            // parameters (<pid> or <exe> <core>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            String params[] = new String[paramCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            for (int i=optionCount; i<args.length; i++ ){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                params[i-optionCount] = args[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            runTool(option, params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            String pid = args[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            // Here we handle the built-in options
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            // As more options are added we should create an abstract tool class and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            // have a table to map the options
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            if (option.equals(HISTO_OPTION)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                histo(pid, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            } else if (option.equals(LIVE_HISTO_OPTION)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                histo(pid, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            } else if (option.startsWith(DUMP_OPTION_PREFIX)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                dump(pid, option);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            } else {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   145
                usage(1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    // Invoke SA tool  with the given arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    private static void runTool(String option, String args[]) throws Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        String[][] tools = {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   153
            { "-pmap",          "pmap"             },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   154
            { "-heap",          "heapSummary"      },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   155
            { "-heap:format=b", "heapDumper"       },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   156
            { "-histo",         "objectHistogram"  },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   157
            { "-clstats",       "classLoaderStats" },
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   158
            { "-finalizerinfo", "finalizerInfo"    },
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   161
        String name = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        // -dump option needs to be handled in a special way
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (option.startsWith(DUMP_OPTION_PREFIX)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            // first check that the option can be parsed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            String fn = parseDumpOptions(option);
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   167
            if (fn == null) {
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   168
                usage(1);
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   169
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            // tool for heap dumping
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   172
            name = "heapDumper";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            // HeapDumper -f <file>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            args = prepend(fn, args);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            args = prepend("-f", args);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            int i=0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            while (i < tools.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                if (option.equals(tools[i][0])) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   181
                    name = tools[i][1];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                i++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   187
        if (name == null) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   188
            usage(1);   // no mapping to tool
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   191
        // Tool not available on this platform.
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   192
        ToolProvider tool = ToolProviderFinder.find(name);
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   193
        if (tool == null) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   194
            usage(1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        // invoke the main method with the arguments
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   198
        tool.run(args);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private static final String LIVE_OBJECTS_OPTION = "-live";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    private static final String ALL_OBJECTS_OPTION = "-all";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    private static void histo(String pid, boolean live) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        VirtualMachine vm = attach(pid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        InputStream in = ((HotSpotVirtualMachine)vm).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            heapHisto(live ? LIVE_OBJECTS_OPTION : ALL_OBJECTS_OPTION);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        drain(vm, in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    private static void dump(String pid, String options) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        // parse the options to get the dump filename
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        String filename = parseDumpOptions(options);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        if (filename == null) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   214
            usage(1);  // invalid options or no filename
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        // get the canonical path - important to avoid just passing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        // a "heap.bin" and having the dump created in the target VM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        // working directory rather than the directory where jmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        // is executed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        filename = new File(filename).getCanonicalPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        // dump live objects only or not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        boolean live = isDumpLiveObjects(options);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        VirtualMachine vm = attach(pid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        System.out.println("Dumping heap to " + filename + " ...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        InputStream in = ((HotSpotVirtualMachine)vm).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            dumpHeap((Object)filename,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                     (live ? LIVE_OBJECTS_OPTION : ALL_OBJECTS_OPTION));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        drain(vm, in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    // Parse the options to the -dump option. Valid options are format=b and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    // file=<file>. Returns <file> if provided. Returns null if <file> not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    // provided, or invalid option.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    private static String parseDumpOptions(String arg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        assert arg.startsWith(DUMP_OPTION_PREFIX);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        String filename = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        // options are separated by comma (,)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        String options[] = arg.substring(DUMP_OPTION_PREFIX.length()).split(",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        for (int i=0; i<options.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            String option = options[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            if (option.equals("format=b")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                // ignore format (not needed at this time)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            } else if (option.equals("live")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                // a valid suboption
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                // file=<file> - check that <file> is specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                if (option.startsWith("file=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                    filename = option.substring(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                    if (filename.length() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                    return null;  // option not recognized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        return filename;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    private static boolean isDumpLiveObjects(String arg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        // options are separated by comma (,)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        String options[] = arg.substring(DUMP_OPTION_PREFIX.length()).split(",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        for (String suboption : options) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            if (suboption.equals("live")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    // Attach to <pid>, existing if we fail to attach
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    private static VirtualMachine attach(String pid) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            return VirtualMachine.attach(pid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        } catch (Exception x) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            String msg = x.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            if (msg != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                System.err.println(pid + ": " + msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                x.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            if ((x instanceof AttachNotSupportedException) && haveSA()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                System.err.println("The -F option can be used when the " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                  "target process is not responding");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            System.exit(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            return null; // keep compiler happy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    // Read the stream from the target VM until EOF, then detach
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    private static void drain(VirtualMachine vm, InputStream in) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        // read to EOF and just print output
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        byte b[] = new byte[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        int n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            n = in.read(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            if (n > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                String s = new String(b, 0, n, "UTF-8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                System.out.print(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        } while (n > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        in.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        vm.detach();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    // return a new string array with arg as the first element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    private static String[] prepend(String arg, String args[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        String[] newargs = new String[args.length+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        newargs[0] = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        System.arraycopy(args, 0, newargs, 1, args.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        return newargs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    // returns true if SA is available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    private static boolean haveSA() {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents: 25859
diff changeset
   325
        return ToolProviderFinder.find("heapSummary") != null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    // print usage message
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   329
    private static void usage(int exit) {
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   330
        System.err.println("Usage:");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (haveSA()) {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   332
            System.err.println("    jmap [option] <pid>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   333
            System.err.println("        (to connect to running process)");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   334
            System.err.println("    jmap [option] <executable <core>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   335
            System.err.println("        (to connect to a core file)");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   336
            System.err.println("    jmap [option] [server_id@]<remote server IP or hostname>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   337
            System.err.println("        (to connect to remote debug server)");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   338
            System.err.println("");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   339
            System.err.println("where <option> is one of:");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   340
            System.err.println("    <none>               to print same info as Solaris pmap");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   341
            System.err.println("    -heap                to print java heap summary");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   342
            System.err.println("    -histo[:live]        to print histogram of java object heap; if the \"live\"");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   343
            System.err.println("                         suboption is specified, only count live objects");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   344
            System.err.println("    -clstats             to print class loader statistics");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   345
            System.err.println("    -finalizerinfo       to print information on objects awaiting finalization");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   346
            System.err.println("    -dump:<dump-options> to dump java heap in hprof binary format");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   347
            System.err.println("                         dump-options:");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   348
            System.err.println("                           live         dump only live objects; if not specified,");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   349
            System.err.println("                                        all objects in the heap are dumped.");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   350
            System.err.println("                           format=b     binary format");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   351
            System.err.println("                           file=<file>  dump heap to <file>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   352
            System.err.println("                         Example: jmap -dump:live,format=b,file=heap.bin <pid>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   353
            System.err.println("    -F                   force. Use with -dump:<dump-options> <pid> or -histo");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   354
            System.err.println("                         to force a heap dump or histogram when <pid> does not");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   355
            System.err.println("                         respond. The \"live\" suboption is not supported");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   356
            System.err.println("                         in this mode.");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   357
            System.err.println("    -h | -help           to print this help message");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   358
            System.err.println("    -J<flag>             to pass <flag> directly to the runtime system");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        } else {
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   360
            System.err.println("    jmap -histo <pid>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   361
            System.err.println("      (to connect to running process and print histogram of java object heap");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   362
            System.err.println("    jmap -dump:<dump-options> <pid>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   363
            System.err.println("      (to connect to running process and dump java heap)");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   364
            System.err.println("");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   365
            System.err.println("    dump-options:");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   366
            System.err.println("      format=b     binary default");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   367
            System.err.println("      file=<file>  dump heap to <file>");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   368
            System.err.println("");
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   369
            System.err.println("    Example:       jmap -dump:format=b,file=heap.bin <pid>");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
21673
c5d341bc60dd 8027765: Make exit codes and stdout/stderr printing from jmap/jinfo/jstack/jps consistent
sla
parents: 21278
diff changeset
   372
        System.exit(exit);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
}