src/share/vm/services/nmtDCmd.cpp

Tue, 30 Apr 2013 09:17:06 -0400

author
zgu
date
Tue, 30 Apr 2013 09:17:06 -0400
changeset 4992
ed5a590835a4
parent 4810
06db4c0afbf3
child 5047
31a4e55f8c9d
permissions
-rw-r--r--

8013214: BigApps fails due to 'fatal error: Illegal threadstate encountered: 6'
Summary: Grab and drop SR_lock to get the thread to honor the safepoint protocol
Reviewed-by: dcubed, coleenp

     1 /*
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    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 #include "precompiled.hpp"
    25 #include "services/nmtDCmd.hpp"
    26 #include "services/memReporter.hpp"
    27 #include "services/memTracker.hpp"
    28 #include "utilities/globalDefinitions.hpp"
    30 NMTDCmd::NMTDCmd(outputStream* output,
    31   bool heap): DCmdWithParser(output, heap),
    32   _summary("summary", "request runtime to report current memory summary, " \
    33            "which includes total reserved and committed memory, along " \
    34            "with memory usage summary by each subsytem.",
    35            "BOOLEAN", false, "false"),
    36   _detail("detail", "request runtime to report memory allocation >= "
    37            "1K by each callsite.",
    38            "BOOLEAN", false, "false"),
    39   _baseline("baseline", "request runtime to baseline current memory usage, " \
    40             "so it can be compared against in later time.",
    41             "BOOLEAN", false, "false"),
    42   _summary_diff("summary.diff", "request runtime to report memory summary " \
    43             "comparison against previous baseline.",
    44             "BOOLEAN", false, "false"),
    45   _detail_diff("detail.diff", "request runtime to report memory detail " \
    46             "comparison against previous baseline, which shows the memory " \
    47             "allocation activities at different callsites.",
    48             "BOOLEAN", false, "false"),
    49   _shutdown("shutdown", "request runtime to shutdown itself and free the " \
    50             "memory used by runtime.",
    51             "BOOLEAN", false, "false"),
    52   _auto_shutdown("autoShutdown", "automatically shutdown itself under "    \
    53             "stress situation",
    54             "BOOLEAN", true, "true"),
    55 #ifndef PRODUCT
    56   _debug("debug", "print tracker statistics. Debug only, not thread safe", \
    57             "BOOLEAN", false, "false"),
    58 #endif
    59   _scale("scale", "Memory usage in which scale, KB, MB or GB",
    60        "STRING", false, "KB") {
    61   _dcmdparser.add_dcmd_option(&_summary);
    62   _dcmdparser.add_dcmd_option(&_detail);
    63   _dcmdparser.add_dcmd_option(&_baseline);
    64   _dcmdparser.add_dcmd_option(&_summary_diff);
    65   _dcmdparser.add_dcmd_option(&_detail_diff);
    66   _dcmdparser.add_dcmd_option(&_shutdown);
    67   _dcmdparser.add_dcmd_option(&_auto_shutdown);
    68 #ifndef PRODUCT
    69   _dcmdparser.add_dcmd_option(&_debug);
    70 #endif
    71   _dcmdparser.add_dcmd_option(&_scale);
    72 }
    74 void NMTDCmd::execute(TRAPS) {
    75   const char* scale_value = _scale.value();
    76   size_t scale_unit;
    77   if (strcmp(scale_value, "KB") == 0 || strcmp(scale_value, "kb") == 0) {
    78     scale_unit = K;
    79   } else if (strcmp(scale_value, "MB") == 0 ||
    80              strcmp(scale_value, "mb") == 0) {
    81     scale_unit = M;
    82   } else if (strcmp(scale_value, "GB") == 0 ||
    83              strcmp(scale_value, "gb") == 0) {
    84     scale_unit = G;
    85   } else {
    86     output()->print_cr("Incorrect scale value: %s", scale_value);
    87     return;
    88   }
    90   int nopt = 0;
    91   if (_summary.is_set() && _summary.value()) { ++nopt; }
    92   if (_detail.is_set() && _detail.value()) { ++nopt; }
    93   if (_baseline.is_set() && _baseline.value()) { ++nopt; }
    94   if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
    95   if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
    96   if (_shutdown.is_set() && _shutdown.value()) { ++nopt; }
    97   if (_auto_shutdown.is_set()) { ++nopt; }
    99 #ifndef PRODUCT
   100   if (_debug.is_set() && _debug.value()) { ++nopt; }
   101 #endif
   103   if (nopt > 1) {
   104       output()->print_cr("At most one of the following option can be specified: " \
   105         "summary, detail, baseline, summary.diff, detail.diff, shutdown"
   106 #ifndef PRODUCT
   107         ", debug"
   108 #endif
   109       );
   110       return;
   111   } else if (nopt == 0) {
   112     if (_summary.is_set()) {
   113       output()->print_cr("No command to execute");
   114       return;
   115     } else {
   116       _summary.set_value(true);
   117     }
   118   }
   120 #ifndef PRODUCT
   121   if (_debug.value()) {
   122     output()->print_cr("debug command is NOT thread-safe, may cause crash");
   123     MemTracker::print_tracker_stats(output());
   124     return;
   125   }
   126 #endif
   128   // native memory tracking has to be on
   129   if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
   130     // if it is not on, what's the reason?
   131     output()->print_cr(MemTracker::reason());
   132     return;
   133   }
   135   if (_summary.value()) {
   136     BaselineTTYOutputer outputer(output());
   137     MemTracker::print_memory_usage(outputer, scale_unit, true);
   138   } else if (_detail.value()) {
   139     BaselineTTYOutputer outputer(output());
   140     MemTracker::print_memory_usage(outputer, scale_unit, false);
   141   } else if (_baseline.value()) {
   142     if (MemTracker::baseline()) {
   143       output()->print_cr("Successfully baselined.");
   144     } else {
   145       output()->print_cr("Baseline failed.");
   146     }
   147   } else if (_summary_diff.value()) {
   148     if (MemTracker::has_baseline()) {
   149       BaselineTTYOutputer outputer(output());
   150       MemTracker::compare_memory_usage(outputer, scale_unit, true);
   151     } else {
   152       output()->print_cr("No baseline to compare, run 'baseline' command first");
   153     }
   154   } else if (_detail_diff.value()) {
   155     if (MemTracker::has_baseline()) {
   156       BaselineTTYOutputer outputer(output());
   157       MemTracker::compare_memory_usage(outputer, scale_unit, false);
   158     } else {
   159       output()->print_cr("No baseline to compare to, run 'baseline' command first");
   160     }
   161   } else if (_shutdown.value()) {
   162     MemTracker::shutdown(MemTracker::NMT_shutdown_user);
   163     output()->print_cr("Shutdown is in progress, it will take a few moments to " \
   164       "completely shutdown");
   165   } else if (_auto_shutdown.is_set()) {
   166     MemTracker::set_autoShutdown(_auto_shutdown.value());
   167   } else {
   168     ShouldNotReachHere();
   169     output()->print_cr("Unknown command");
   170   }
   171 }
   173 int NMTDCmd::num_arguments() {
   174   ResourceMark rm;
   175   NMTDCmd* dcmd = new NMTDCmd(NULL, false);
   176   if (dcmd != NULL) {
   177     DCmdMark mark(dcmd);
   178     return dcmd->_dcmdparser.num_arguments();
   179   } else {
   180     return 0;
   181   }
   182 }

mercurial