src/share/vm/services/nmtDCmd.cpp

changeset 7074
833b0f92429a
parent 6680
78bbf4d43a14
child 7535
7ae4e26cb1e0
     1.1 --- a/src/share/vm/services/nmtDCmd.cpp	Wed Aug 27 09:36:55 2014 +0200
     1.2 +++ b/src/share/vm/services/nmtDCmd.cpp	Wed Aug 27 08:19:12 2014 -0400
     1.3 @@ -22,6 +22,8 @@
     1.4   *
     1.5   */
     1.6  #include "precompiled.hpp"
     1.7 +
     1.8 +#include "runtime/mutexLocker.hpp"
     1.9  #include "services/nmtDCmd.hpp"
    1.10  #include "services/memReporter.hpp"
    1.11  #include "services/memTracker.hpp"
    1.12 @@ -49,13 +51,8 @@
    1.13    _shutdown("shutdown", "request runtime to shutdown itself and free the " \
    1.14              "memory used by runtime.",
    1.15              "BOOLEAN", false, "false"),
    1.16 -  _auto_shutdown("autoShutdown", "automatically shutdown itself under "    \
    1.17 -            "stress situation",
    1.18 -            "BOOLEAN", true, "true"),
    1.19 -#ifndef PRODUCT
    1.20 -  _debug("debug", "print tracker statistics. Debug only, not thread safe", \
    1.21 +  _statistics("statistics", "print tracker statistics for tuning purpose.", \
    1.22              "BOOLEAN", false, "false"),
    1.23 -#endif
    1.24    _scale("scale", "Memory usage in which scale, KB, MB or GB",
    1.25         "STRING", false, "KB") {
    1.26    _dcmdparser.add_dcmd_option(&_summary);
    1.27 @@ -64,25 +61,30 @@
    1.28    _dcmdparser.add_dcmd_option(&_summary_diff);
    1.29    _dcmdparser.add_dcmd_option(&_detail_diff);
    1.30    _dcmdparser.add_dcmd_option(&_shutdown);
    1.31 -  _dcmdparser.add_dcmd_option(&_auto_shutdown);
    1.32 -#ifndef PRODUCT
    1.33 -  _dcmdparser.add_dcmd_option(&_debug);
    1.34 -#endif
    1.35 +  _dcmdparser.add_dcmd_option(&_statistics);
    1.36    _dcmdparser.add_dcmd_option(&_scale);
    1.37  }
    1.38  
    1.39 +
    1.40 +size_t NMTDCmd::get_scale(const char* scale) const {
    1.41 +  if (scale == NULL) return 0;
    1.42 +  return NMTUtil::scale_from_name(scale);
    1.43 +}
    1.44 +
    1.45  void NMTDCmd::execute(DCmdSource source, TRAPS) {
    1.46 +  // Check NMT state
    1.47 +  //  native memory tracking has to be on
    1.48 +  if (MemTracker::tracking_level() == NMT_off) {
    1.49 +    output()->print_cr("Native memory tracking is not enabled");
    1.50 +    return;
    1.51 +  } else if (MemTracker::tracking_level() == NMT_minimal) {
    1.52 +     output()->print_cr("Native memory tracking has been shutdown");
    1.53 +     return;
    1.54 +  }
    1.55 +
    1.56    const char* scale_value = _scale.value();
    1.57 -  size_t scale_unit;
    1.58 -  if (strcmp(scale_value, "KB") == 0 || strcmp(scale_value, "kb") == 0) {
    1.59 -    scale_unit = K;
    1.60 -  } else if (strcmp(scale_value, "MB") == 0 ||
    1.61 -             strcmp(scale_value, "mb") == 0) {
    1.62 -    scale_unit = M;
    1.63 -  } else if (strcmp(scale_value, "GB") == 0 ||
    1.64 -             strcmp(scale_value, "gb") == 0) {
    1.65 -    scale_unit = G;
    1.66 -  } else {
    1.67 +  size_t scale_unit = get_scale(scale_value);
    1.68 +  if (scale_unit == 0) {
    1.69      output()->print_cr("Incorrect scale value: %s", scale_value);
    1.70      return;
    1.71    }
    1.72 @@ -94,19 +96,11 @@
    1.73    if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
    1.74    if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
    1.75    if (_shutdown.is_set() && _shutdown.value()) { ++nopt; }
    1.76 -  if (_auto_shutdown.is_set()) { ++nopt; }
    1.77 -
    1.78 -#ifndef PRODUCT
    1.79 -  if (_debug.is_set() && _debug.value()) { ++nopt; }
    1.80 -#endif
    1.81 +  if (_statistics.is_set() && _statistics.value()) { ++nopt; }
    1.82  
    1.83    if (nopt > 1) {
    1.84        output()->print_cr("At most one of the following option can be specified: " \
    1.85 -        "summary, detail, baseline, summary.diff, detail.diff, shutdown"
    1.86 -#ifndef PRODUCT
    1.87 -        ", debug"
    1.88 -#endif
    1.89 -      );
    1.90 +        "summary, detail, baseline, summary.diff, detail.diff, shutdown");
    1.91        return;
    1.92    } else if (nopt == 0) {
    1.93      if (_summary.is_set()) {
    1.94 @@ -117,53 +111,47 @@
    1.95      }
    1.96    }
    1.97  
    1.98 -#ifndef PRODUCT
    1.99 -  if (_debug.value()) {
   1.100 -    output()->print_cr("debug command is NOT thread-safe, may cause crash");
   1.101 -    MemTracker::print_tracker_stats(output());
   1.102 +  // Serialize NMT query
   1.103 +  MutexLocker locker(MemTracker::query_lock());
   1.104 +
   1.105 +  if (_summary.value()) {
   1.106 +    report(true, scale_unit);
   1.107 +  } else if (_detail.value()) {
   1.108 +    if (!check_detail_tracking_level(output())) {
   1.109      return;
   1.110    }
   1.111 -#endif
   1.112 -
   1.113 -  // native memory tracking has to be on
   1.114 -  if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
   1.115 -    // if it is not on, what's the reason?
   1.116 -    output()->print_cr("%s", MemTracker::reason());
   1.117 +    report(false, scale_unit);
   1.118 +  } else if (_baseline.value()) {
   1.119 +    MemBaseline& baseline = MemTracker::get_baseline();
   1.120 +    if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
   1.121 +      output()->print_cr("Baseline failed");
   1.122 +    } else {
   1.123 +      output()->print_cr("Baseline succeeded");
   1.124 +    }
   1.125 +  } else if (_summary_diff.value()) {
   1.126 +    MemBaseline& baseline = MemTracker::get_baseline();
   1.127 +    if (baseline.baseline_type() >= MemBaseline::Summary_baselined) {
   1.128 +      report_diff(true, scale_unit);
   1.129 +    } else {
   1.130 +      output()->print_cr("No baseline for comparison");
   1.131 +    }
   1.132 +  } else if (_detail_diff.value()) {
   1.133 +    if (!check_detail_tracking_level(output())) {
   1.134      return;
   1.135    }
   1.136 -
   1.137 -  if (_summary.value()) {
   1.138 -    BaselineTTYOutputer outputer(output());
   1.139 -    MemTracker::print_memory_usage(outputer, scale_unit, true);
   1.140 -  } else if (_detail.value()) {
   1.141 -    BaselineTTYOutputer outputer(output());
   1.142 -    MemTracker::print_memory_usage(outputer, scale_unit, false);
   1.143 -  } else if (_baseline.value()) {
   1.144 -    if (MemTracker::baseline()) {
   1.145 -      output()->print_cr("Successfully baselined.");
   1.146 +    MemBaseline& baseline = MemTracker::get_baseline();
   1.147 +    if (baseline.baseline_type() == MemBaseline::Detail_baselined) {
   1.148 +      report_diff(false, scale_unit);
   1.149      } else {
   1.150 -      output()->print_cr("Baseline failed.");
   1.151 -    }
   1.152 -  } else if (_summary_diff.value()) {
   1.153 -    if (MemTracker::has_baseline()) {
   1.154 -      BaselineTTYOutputer outputer(output());
   1.155 -      MemTracker::compare_memory_usage(outputer, scale_unit, true);
   1.156 -    } else {
   1.157 -      output()->print_cr("No baseline to compare, run 'baseline' command first");
   1.158 -    }
   1.159 -  } else if (_detail_diff.value()) {
   1.160 -    if (MemTracker::has_baseline()) {
   1.161 -      BaselineTTYOutputer outputer(output());
   1.162 -      MemTracker::compare_memory_usage(outputer, scale_unit, false);
   1.163 -    } else {
   1.164 -      output()->print_cr("No baseline to compare to, run 'baseline' command first");
   1.165 +      output()->print_cr("No detail baseline for comparison");
   1.166      }
   1.167    } else if (_shutdown.value()) {
   1.168 -    MemTracker::shutdown(MemTracker::NMT_shutdown_user);
   1.169 -    output()->print_cr("Shutdown is in progress, it will take a few moments to " \
   1.170 -      "completely shutdown");
   1.171 -  } else if (_auto_shutdown.is_set()) {
   1.172 -    MemTracker::set_autoShutdown(_auto_shutdown.value());
   1.173 +    MemTracker::shutdown();
   1.174 +    output()->print_cr("Native memory tracking has been turned off");
   1.175 +  } else if (_statistics.value()) {
   1.176 +    if (check_detail_tracking_level(output())) {
   1.177 +      MemTracker::tuning_statistics(output());
   1.178 +    }
   1.179    } else {
   1.180      ShouldNotReachHere();
   1.181      output()->print_cr("Unknown command");
   1.182 @@ -181,3 +169,46 @@
   1.183    }
   1.184  }
   1.185  
   1.186 +void NMTDCmd::report(bool summaryOnly, size_t scale_unit) {
   1.187 +  MemBaseline baseline;
   1.188 +  if (baseline.baseline(summaryOnly)) {
   1.189 +    if (summaryOnly) {
   1.190 +      MemSummaryReporter rpt(baseline, output(), scale_unit);
   1.191 +      rpt.report();
   1.192 +    } else {
   1.193 +      MemDetailReporter rpt(baseline, output(), scale_unit);
   1.194 +      rpt.report();
   1.195 +    }
   1.196 +  }
   1.197 +}
   1.198 +
   1.199 +void NMTDCmd::report_diff(bool summaryOnly, size_t scale_unit) {
   1.200 +  MemBaseline& early_baseline = MemTracker::get_baseline();
   1.201 +  assert(early_baseline.baseline_type() != MemBaseline::Not_baselined,
   1.202 +    "Not yet baselined");
   1.203 +  assert(summaryOnly || early_baseline.baseline_type() == MemBaseline::Detail_baselined,
   1.204 +    "Not a detail baseline");
   1.205 +
   1.206 +  MemBaseline baseline;
   1.207 +  if (baseline.baseline(summaryOnly)) {
   1.208 +    if (summaryOnly) {
   1.209 +      MemSummaryDiffReporter rpt(early_baseline, baseline, output(), scale_unit);
   1.210 +      rpt.report_diff();
   1.211 +    } else {
   1.212 +      MemDetailDiffReporter rpt(early_baseline, baseline, output(), scale_unit);
   1.213 +      rpt.report_diff();
   1.214 +    }
   1.215 +  }
   1.216 +}
   1.217 +
   1.218 +bool NMTDCmd::check_detail_tracking_level(outputStream* out) {
   1.219 +  if (MemTracker::tracking_level() == NMT_detail) {
   1.220 +    return true;
   1.221 +  } else if (MemTracker::cmdline_tracking_level() == NMT_detail) {
   1.222 +    out->print_cr("Tracking level has been downgraded due to lack of resources");
   1.223 +    return false;
   1.224 +  } else {
   1.225 +    out->print_cr("Detail tracking is not enabled");
   1.226 +    return false;
   1.227 +  }
   1.228 +}

mercurial