Mercurial > hg > truffle
annotate src/share/vm/services/nmtDCmd.cpp @ 21645:7eb156f30b61
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Mon, 01 Jun 2015 22:13:10 +0200 |
parents | 833b0f92429a |
children |
rev | line source |
---|---|
6197 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
10215
diff
changeset
|
2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. |
6197 | 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" | |
20360 | 25 |
26 #include "runtime/mutexLocker.hpp" | |
6197 | 27 #include "services/nmtDCmd.hpp" |
28 #include "services/memReporter.hpp" | |
29 #include "services/memTracker.hpp" | |
30 #include "utilities/globalDefinitions.hpp" | |
31 | |
32 NMTDCmd::NMTDCmd(outputStream* output, | |
33 bool heap): DCmdWithParser(output, heap), | |
34 _summary("summary", "request runtime to report current memory summary, " \ | |
35 "which includes total reserved and committed memory, along " \ | |
36 "with memory usage summary by each subsytem.", | |
37 "BOOLEAN", false, "false"), | |
38 _detail("detail", "request runtime to report memory allocation >= " | |
39 "1K by each callsite.", | |
40 "BOOLEAN", false, "false"), | |
41 _baseline("baseline", "request runtime to baseline current memory usage, " \ | |
42 "so it can be compared against in later time.", | |
43 "BOOLEAN", false, "false"), | |
44 _summary_diff("summary.diff", "request runtime to report memory summary " \ | |
45 "comparison against previous baseline.", | |
46 "BOOLEAN", false, "false"), | |
47 _detail_diff("detail.diff", "request runtime to report memory detail " \ | |
48 "comparison against previous baseline, which shows the memory " \ | |
49 "allocation activities at different callsites.", | |
50 "BOOLEAN", false, "false"), | |
51 _shutdown("shutdown", "request runtime to shutdown itself and free the " \ | |
52 "memory used by runtime.", | |
53 "BOOLEAN", false, "false"), | |
20360 | 54 _statistics("statistics", "print tracker statistics for tuning purpose.", \ |
6197 | 55 "BOOLEAN", false, "false"), |
56 _scale("scale", "Memory usage in which scale, KB, MB or GB", | |
57 "STRING", false, "KB") { | |
58 _dcmdparser.add_dcmd_option(&_summary); | |
59 _dcmdparser.add_dcmd_option(&_detail); | |
60 _dcmdparser.add_dcmd_option(&_baseline); | |
61 _dcmdparser.add_dcmd_option(&_summary_diff); | |
62 _dcmdparser.add_dcmd_option(&_detail_diff); | |
63 _dcmdparser.add_dcmd_option(&_shutdown); | |
20360 | 64 _dcmdparser.add_dcmd_option(&_statistics); |
6197 | 65 _dcmdparser.add_dcmd_option(&_scale); |
66 } | |
67 | |
20360 | 68 |
69 size_t NMTDCmd::get_scale(const char* scale) const { | |
70 if (scale == NULL) return 0; | |
71 return NMTUtil::scale_from_name(scale); | |
72 } | |
73 | |
10215
31a4e55f8c9d
8004095: Add support for JMX interface to Diagnostic Framework and Commands
fparain
parents:
8810
diff
changeset
|
74 void NMTDCmd::execute(DCmdSource source, TRAPS) { |
20360 | 75 // Check NMT state |
76 // native memory tracking has to be on | |
77 if (MemTracker::tracking_level() == NMT_off) { | |
78 output()->print_cr("Native memory tracking is not enabled"); | |
79 return; | |
80 } else if (MemTracker::tracking_level() == NMT_minimal) { | |
81 output()->print_cr("Native memory tracking has been shutdown"); | |
82 return; | |
83 } | |
84 | |
6197 | 85 const char* scale_value = _scale.value(); |
20360 | 86 size_t scale_unit = get_scale(scale_value); |
87 if (scale_unit == 0) { | |
6197 | 88 output()->print_cr("Incorrect scale value: %s", scale_value); |
89 return; | |
90 } | |
91 | |
92 int nopt = 0; | |
8810
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
93 if (_summary.is_set() && _summary.value()) { ++nopt; } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
94 if (_detail.is_set() && _detail.value()) { ++nopt; } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
95 if (_baseline.is_set() && _baseline.value()) { ++nopt; } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
96 if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
97 if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; } |
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
98 if (_shutdown.is_set() && _shutdown.value()) { ++nopt; } |
20360 | 99 if (_statistics.is_set() && _statistics.value()) { ++nopt; } |
6197 | 100 |
8810
06db4c0afbf3
8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT
zgu
parents:
7412
diff
changeset
|
101 if (nopt > 1) { |
6197 | 102 output()->print_cr("At most one of the following option can be specified: " \ |
20360 | 103 "summary, detail, baseline, summary.diff, detail.diff, shutdown"); |
6197 | 104 return; |
7412
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
105 } else if (nopt == 0) { |
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
106 if (_summary.is_set()) { |
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
107 output()->print_cr("No command to execute"); |
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
108 return; |
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
109 } else { |
6197 | 110 _summary.set_value(true); |
7412
3f84e17b6bca
8004802: jcmd VM.native_memory baseline=false crashes VM
zgu
parents:
6197
diff
changeset
|
111 } |
6197 | 112 } |
113 | |
20360 | 114 // Serialize NMT query |
115 MutexLocker locker(MemTracker::query_lock()); | |
6197 | 116 |
117 if (_summary.value()) { | |
20360 | 118 report(true, scale_unit); |
6197 | 119 } else if (_detail.value()) { |
20360 | 120 if (!check_detail_tracking_level(output())) { |
121 return; | |
122 } | |
123 report(false, scale_unit); | |
6197 | 124 } else if (_baseline.value()) { |
20360 | 125 MemBaseline& baseline = MemTracker::get_baseline(); |
126 if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) { | |
127 output()->print_cr("Baseline failed"); | |
6197 | 128 } else { |
20360 | 129 output()->print_cr("Baseline succeeded"); |
6197 | 130 } |
131 } else if (_summary_diff.value()) { | |
20360 | 132 MemBaseline& baseline = MemTracker::get_baseline(); |
133 if (baseline.baseline_type() >= MemBaseline::Summary_baselined) { | |
134 report_diff(true, scale_unit); | |
6197 | 135 } else { |
20360 | 136 output()->print_cr("No baseline for comparison"); |
6197 | 137 } |
138 } else if (_detail_diff.value()) { | |
20360 | 139 if (!check_detail_tracking_level(output())) { |
140 return; | |
141 } | |
142 MemBaseline& baseline = MemTracker::get_baseline(); | |
143 if (baseline.baseline_type() == MemBaseline::Detail_baselined) { | |
144 report_diff(false, scale_unit); | |
6197 | 145 } else { |
20360 | 146 output()->print_cr("No detail baseline for comparison"); |
6197 | 147 } |
148 } else if (_shutdown.value()) { | |
20360 | 149 MemTracker::shutdown(); |
150 output()->print_cr("Native memory tracking has been turned off"); | |
151 } else if (_statistics.value()) { | |
152 if (check_detail_tracking_level(output())) { | |
153 MemTracker::tuning_statistics(output()); | |
154 } | |
6197 | 155 } else { |
156 ShouldNotReachHere(); | |
157 output()->print_cr("Unknown command"); | |
158 } | |
159 } | |
160 | |
161 int NMTDCmd::num_arguments() { | |
162 ResourceMark rm; | |
163 NMTDCmd* dcmd = new NMTDCmd(NULL, false); | |
164 if (dcmd != NULL) { | |
165 DCmdMark mark(dcmd); | |
166 return dcmd->_dcmdparser.num_arguments(); | |
167 } else { | |
168 return 0; | |
169 } | |
170 } | |
171 | |
20360 | 172 void NMTDCmd::report(bool summaryOnly, size_t scale_unit) { |
173 MemBaseline baseline; | |
174 if (baseline.baseline(summaryOnly)) { | |
175 if (summaryOnly) { | |
176 MemSummaryReporter rpt(baseline, output(), scale_unit); | |
177 rpt.report(); | |
178 } else { | |
179 MemDetailReporter rpt(baseline, output(), scale_unit); | |
180 rpt.report(); | |
181 } | |
182 } | |
183 } | |
184 | |
185 void NMTDCmd::report_diff(bool summaryOnly, size_t scale_unit) { | |
186 MemBaseline& early_baseline = MemTracker::get_baseline(); | |
187 assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, | |
188 "Not yet baselined"); | |
189 assert(summaryOnly || early_baseline.baseline_type() == MemBaseline::Detail_baselined, | |
190 "Not a detail baseline"); | |
191 | |
192 MemBaseline baseline; | |
193 if (baseline.baseline(summaryOnly)) { | |
194 if (summaryOnly) { | |
195 MemSummaryDiffReporter rpt(early_baseline, baseline, output(), scale_unit); | |
196 rpt.report_diff(); | |
197 } else { | |
198 MemDetailDiffReporter rpt(early_baseline, baseline, output(), scale_unit); | |
199 rpt.report_diff(); | |
200 } | |
201 } | |
202 } | |
203 | |
204 bool NMTDCmd::check_detail_tracking_level(outputStream* out) { | |
205 if (MemTracker::tracking_level() == NMT_detail) { | |
206 return true; | |
207 } else if (MemTracker::cmdline_tracking_level() == NMT_detail) { | |
208 out->print_cr("Tracking level has been downgraded due to lack of resources"); | |
209 return false; | |
210 } else { | |
211 out->print_cr("Detail tracking is not enabled"); | |
212 return false; | |
213 } | |
214 } |