158 assert(level != NMT_off || current_level == NMT_off, "Cannot transition NMT to off");
159
160 if (current_level == level) {
161 return true;
162 } else if (current_level > level) {
163 // Downgrade tracking level, we want to lower the tracking level first
164 _tracking_level = level;
165 // Make _tracking_level visible immediately.
166 OrderAccess::fence();
167 VirtualMemoryTracker::transition(current_level, level);
168 MallocTracker::transition(current_level, level);
169 ThreadStackTracker::transition(current_level, level);
170 } else {
171 // Upgrading tracking level is not supported and has never been supported.
172 // Allocating and deallocating malloc tracking structures is not thread safe and
173 // leads to inconsistencies unless a lot coarser locks are added.
174 }
175 return true;
176 }
177
178 void MemTracker::report(bool summary_only, outputStream* output) {
179 assert(output != NULL, "No output stream");
180 MemBaseline baseline;
181 if (baseline.baseline(summary_only)) {
182 if (summary_only) {
183 MemSummaryReporter rpt(baseline, output);
184 rpt.report();
185 } else {
186 MemDetailReporter rpt(baseline, output);
187 rpt.report();
188 output->print("Metaspace:");
189 // Metadata reporting requires a safepoint, so avoid it if VM is not in good state.
190 assert(!VMError::fatal_error_in_progress(), "Do not report metadata in error report");
191 VM_PrintMetadata vmop(output, K,
192 MetaspaceUtils::rf_show_loaders |
193 MetaspaceUtils::rf_break_down_by_spacetype);
194 VMThread::execute(&vmop);
195 }
196 }
197 }
198
199 // This is a walker to gather malloc site hashtable statistics,
200 // the result is used for tuning.
201 class StatisticsWalker : public MallocSiteWalker {
202 private:
203 enum Threshold {
204 // aggregates statistics over this threshold into one
205 // line item.
206 report_threshold = 20
207 };
208
209 private:
210 // Number of allocation sites that have all memory freed
211 int _empty_entries;
212 // Total number of allocation sites, include empty sites
213 int _total_entries;
214 // Number of captured call stack distribution
|
158 assert(level != NMT_off || current_level == NMT_off, "Cannot transition NMT to off");
159
160 if (current_level == level) {
161 return true;
162 } else if (current_level > level) {
163 // Downgrade tracking level, we want to lower the tracking level first
164 _tracking_level = level;
165 // Make _tracking_level visible immediately.
166 OrderAccess::fence();
167 VirtualMemoryTracker::transition(current_level, level);
168 MallocTracker::transition(current_level, level);
169 ThreadStackTracker::transition(current_level, level);
170 } else {
171 // Upgrading tracking level is not supported and has never been supported.
172 // Allocating and deallocating malloc tracking structures is not thread safe and
173 // leads to inconsistencies unless a lot coarser locks are added.
174 }
175 return true;
176 }
177
178
179 static volatile bool g_final_report_did_run = false;
180 void MemTracker::final_report(outputStream* output) {
181 // This function is called during both error reporting and normal VM exit.
182 // However, it should only ever run once. E.g. if the VM crashes after
183 // printing the final report during normal VM exit, it should not print
184 // the final report again. In addition, it should be guarded from
185 // recursive calls in case NMT reporting itself crashes.
186 if (Atomic::cmpxchg(true, &g_final_report_did_run, false) == false) {
187 NMT_TrackingLevel level = tracking_level();
188 if (level >= NMT_summary) {
189 report(level == NMT_summary, output);
190 }
191 }
192 }
193
194 void MemTracker::report(bool summary_only, outputStream* output) {
195 assert(output != NULL, "No output stream");
196 MemBaseline baseline;
197 if (baseline.baseline(summary_only)) {
198 if (summary_only) {
199 MemSummaryReporter rpt(baseline, output);
200 rpt.report();
201 } else {
202 MemDetailReporter rpt(baseline, output);
203 rpt.report();
204 output->print("Metaspace:");
205 // The basic metaspace report avoids any locking and should be safe to
206 // be called at any time.
207 MetaspaceUtils::print_basic_report(output, K);
208 }
209 }
210 }
211
212 // This is a walker to gather malloc site hashtable statistics,
213 // the result is used for tuning.
214 class StatisticsWalker : public MallocSiteWalker {
215 private:
216 enum Threshold {
217 // aggregates statistics over this threshold into one
218 // line item.
219 report_threshold = 20
220 };
221
222 private:
223 // Number of allocation sites that have all memory freed
224 int _empty_entries;
225 // Total number of allocation sites, include empty sites
226 int _total_entries;
227 // Number of captured call stack distribution
|