142 ShouldNotReachHere(); |
142 ShouldNotReachHere(); |
143 } |
143 } |
144 } |
144 } |
145 |
145 |
146 |
146 |
147 // Shutdown can only be issued via JCmd, and NMT JCmd is serialized |
147 // Shutdown can only be issued via JCmd, and NMT JCmd is serialized by lock |
148 // by lock |
|
149 void MemTracker::shutdown() { |
148 void MemTracker::shutdown() { |
150 // We can only shutdown NMT to minimal tracking level if it is |
149 // We can only shutdown NMT to minimal tracking level if it is ever on. |
151 // ever on. |
|
152 if (tracking_level () > NMT_minimal) { |
150 if (tracking_level () > NMT_minimal) { |
153 transition_to(NMT_minimal); |
151 transition_to(NMT_minimal); |
154 } |
152 } |
155 } |
153 } |
156 |
154 |
157 bool MemTracker::transition_to(NMT_TrackingLevel level) { |
155 bool MemTracker::transition_to(NMT_TrackingLevel level) { |
158 NMT_TrackingLevel current_level = tracking_level(); |
156 NMT_TrackingLevel current_level = tracking_level(); |
|
157 |
|
158 assert(level != NMT_off || current_level == NMT_off, "Cannot transition NMT to off"); |
159 |
159 |
160 if (current_level == level) { |
160 if (current_level == level) { |
161 return true; |
161 return true; |
162 } else if (current_level > level) { |
162 } else if (current_level > level) { |
163 // Downgrade tracking level, we want to lower the tracking |
163 // Downgrade tracking level, we want to lower the tracking level first |
164 // level first |
|
165 _tracking_level = level; |
164 _tracking_level = level; |
166 // Make _tracking_level visible immediately. |
165 // Make _tracking_level visible immediately. |
167 OrderAccess::fence(); |
166 OrderAccess::fence(); |
168 VirtualMemoryTracker::transition(current_level, level); |
167 VirtualMemoryTracker::transition(current_level, level); |
169 MallocTracker::transition(current_level, level); |
168 MallocTracker::transition(current_level, level); |
170 |
|
171 if (level == NMT_minimal) _baseline.reset(); |
|
172 } else { |
169 } else { |
173 VirtualMemoryTracker::transition(current_level, level); |
170 // Upgrading tracking level is not supported and has never been supported. |
174 MallocTracker::transition(current_level, level); |
171 // Allocating and deallocating malloc tracking structures is not thread safe and |
175 |
172 // leads to inconsistencies unless a lot coarser locks are added. |
176 _tracking_level = level; |
173 } |
177 // Make _tracking_level visible immediately. |
|
178 OrderAccess::fence(); |
|
179 } |
|
180 |
|
181 return true; |
174 return true; |
182 } |
175 } |
183 |
176 |
184 void MemTracker::final_report(outputStream* output) { |
177 void MemTracker::report(bool summary_only, outputStream* output) { |
185 assert(output != NULL, "No output stream"); |
178 assert(output != NULL, "No output stream"); |
186 if (tracking_level() >= NMT_summary) { |
179 MemBaseline baseline; |
187 MallocMemorySnapshot* malloc_memory_snapshot = |
180 if (baseline.baseline(summary_only)) { |
188 MallocMemorySummary::as_snapshot(); |
181 if (summary_only) { |
189 malloc_memory_snapshot->make_adjustment(); |
182 MemSummaryReporter rpt(baseline, output); |
190 |
183 rpt.report(); |
191 VirtualMemorySnapshot* virtual_memory_snapshot = |
184 } else { |
192 VirtualMemorySummary::as_snapshot(); |
185 MemDetailReporter rpt(baseline, output); |
193 |
186 rpt.report(); |
194 MemSummaryReporter rptr(malloc_memory_snapshot, |
187 } |
195 virtual_memory_snapshot, output); |
|
196 rptr.report(); |
|
197 // shutdown NMT, the data no longer accurate |
|
198 shutdown(); |
|
199 } |
188 } |
200 } |
189 } |
201 |
190 |
202 // This is a walker to gather malloc site hashtable statistics, |
191 // This is a walker to gather malloc site hashtable statistics, |
203 // the result is used for tuning. |
192 // the result is used for tuning. |