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.
|
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(&g_final_report_did_run, false, true) == 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.
|