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"
25 #include "jvm.h"
26
27 #include "runtime/mutex.hpp"
28 #include "runtime/orderAccess.hpp"
29 #include "runtime/vmThread.hpp"
30 #include "runtime/vm_operations.hpp"
31 #include "services/memBaseline.hpp"
32 #include "services/memReporter.hpp"
33 #include "services/mallocTracker.inline.hpp"
34 #include "services/memTracker.hpp"
35 #include "utilities/defaultStream.hpp"
36 #include "utilities/vmError.hpp"
37
38 #ifdef SOLARIS
39 volatile bool NMT_stack_walkable = false;
40 #else
41 volatile bool NMT_stack_walkable = true;
42 #endif
43
44 volatile NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown;
45 NMT_TrackingLevel MemTracker::_cmdline_tracking_level = NMT_unknown;
46
47 MemBaseline MemTracker::_baseline;
48 Mutex* MemTracker::_query_lock = NULL;
292 out->print_cr("Call stack depth distribution:");
293 for (index = 0; index < NMT_TrackingStackDepth; index ++) {
294 if (_stack_depth_distribution[index] > 0) {
295 out->print_cr("\t%d: %d", index + 1, _stack_depth_distribution[index]);
296 }
297 }
298 }
299
300 private:
301 void record_bucket_length(int length) {
302 _used_buckets ++;
303 if (length <= report_threshold) {
304 _hash_distribution[length - 1] ++;
305 } else {
306 _bucket_over_threshold ++;
307 }
308 _longest_bucket_length = MAX2(_longest_bucket_length, length);
309 }
310 };
311
312
313 void MemTracker::tuning_statistics(outputStream* out) {
314 // NMT statistics
315 StatisticsWalker walker;
316 MallocSiteTable::walk_malloc_site(&walker);
317 walker.completed();
318
319 out->print_cr("Native Memory Tracking Statistics:");
320 out->print_cr("Malloc allocation site table size: %d", MallocSiteTable::hash_buckets());
321 out->print_cr(" Tracking stack depth: %d", NMT_TrackingStackDepth);
322 NOT_PRODUCT(out->print_cr("Peak concurrent access: %d", MallocSiteTable::access_peak_count());)
323 out->print_cr(" ");
324 walker.report_statistics(out);
325 }
|
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"
25 #include "jvm.h"
26
27 #include "runtime/mutex.hpp"
28 #include "runtime/orderAccess.hpp"
29 #include "runtime/os.hpp"
30 #include "runtime/vmThread.hpp"
31 #include "runtime/vm_operations.hpp"
32 #include "services/memBaseline.hpp"
33 #include "services/memReporter.hpp"
34 #include "services/mallocTracker.inline.hpp"
35 #include "services/memTracker.hpp"
36 #include "utilities/defaultStream.hpp"
37 #include "utilities/vmError.hpp"
38
39 #ifdef SOLARIS
40 volatile bool NMT_stack_walkable = false;
41 #else
42 volatile bool NMT_stack_walkable = true;
43 #endif
44
45 volatile NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown;
46 NMT_TrackingLevel MemTracker::_cmdline_tracking_level = NMT_unknown;
47
48 MemBaseline MemTracker::_baseline;
49 Mutex* MemTracker::_query_lock = NULL;
293 out->print_cr("Call stack depth distribution:");
294 for (index = 0; index < NMT_TrackingStackDepth; index ++) {
295 if (_stack_depth_distribution[index] > 0) {
296 out->print_cr("\t%d: %d", index + 1, _stack_depth_distribution[index]);
297 }
298 }
299 }
300
301 private:
302 void record_bucket_length(int length) {
303 _used_buckets ++;
304 if (length <= report_threshold) {
305 _hash_distribution[length - 1] ++;
306 } else {
307 _bucket_over_threshold ++;
308 }
309 _longest_bucket_length = MAX2(_longest_bucket_length, length);
310 }
311 };
312
313
314 void MemTracker::record_thread_stack(void* addr, size_t size) {
315 if (tracking_level() < NMT_summary) return;
316 if (addr != NULL) {
317 // uses thread stack malloc slot for book keeping number of threads
318 MallocMemorySummary::record_malloc(0, mtThreadStack);
319 // NMT assumes thread stacks to be page aligned; but that does not have to be the case.
320 // So, for the purpose of keeping track of thread stacks, just use the inner page aligned
321 // part of the thread stack.
322 const os::range_t inner = os::inner_page_aligned_boundaries((address)addr, size);
323 record_virtual_memory_reserve(inner.addr, inner.size, CALLER_PC, mtThreadStack);
324 }
325 }
326
327 void MemTracker::release_thread_stack(void* addr, size_t size) {
328 if (tracking_level() < NMT_summary) return;
329 if (addr != NULL) {
330 // uses thread stack malloc slot for book keeping number of threads
331 MallocMemorySummary::record_free(0, mtThreadStack);
332 ThreadCritical tc;
333 if (tracking_level() < NMT_summary) return;
334 // NMT assumes thread stacks to be page aligned; but that does not have to be the case.
335 // So, for the purpose of keeping track of thread stacks, just use the inner page aligned
336 // part of the thread stack.
337 const os::range_t inner = os::inner_page_aligned_boundaries((address)addr, size);
338 VirtualMemoryTracker::remove_released_region(inner.addr, inner.size);
339 }
340 }
341
342 void MemTracker::tuning_statistics(outputStream* out) {
343 // NMT statistics
344 StatisticsWalker walker;
345 MallocSiteTable::walk_malloc_site(&walker);
346 walker.completed();
347
348 out->print_cr("Native Memory Tracking Statistics:");
349 out->print_cr("Malloc allocation site table size: %d", MallocSiteTable::hash_buckets());
350 out->print_cr(" Tracking stack depth: %d", NMT_TrackingStackDepth);
351 NOT_PRODUCT(out->print_cr("Peak concurrent access: %d", MallocSiteTable::access_peak_count());)
352 out->print_cr(" ");
353 walker.report_statistics(out);
354 }
|