2
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2020, 2023 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
25
#include "precompiled.hpp"
27
#include "logging/log.hpp"
28
#include "logging/logStream.hpp"
29
#include "memory/metaspaceUtils.hpp"
30
#include "nmt/mallocLimit.hpp"
31
#include "nmt/mallocTracker.hpp"
32
#include "nmt/memBaseline.hpp"
33
#include "nmt/memReporter.hpp"
34
#include "nmt/memTracker.hpp"
35
#include "nmt/nmtCommon.hpp"
36
#include "nmt/nmtPreInit.hpp"
37
#include "nmt/threadStackTracker.hpp"
38
#include "runtime/atomic.hpp"
39
#include "runtime/globals.hpp"
40
#include "runtime/orderAccess.hpp"
41
#include "runtime/vmOperations.hpp"
42
#include "runtime/vmThread.hpp"
43
#include "utilities/debug.hpp"
44
#include "utilities/defaultStream.hpp"
45
#include "utilities/vmError.hpp"
51
NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown;
53
MemBaseline MemTracker::_baseline;
55
void MemTracker::initialize() {
57
assert(_tracking_level == NMT_unknown, "only call once");
59
NMT_TrackingLevel level = NMTUtil::parse_tracking_level(NativeMemoryTracking);
60
// Should have been validated before in arguments.cpp
61
assert(level == NMT_off || level == NMT_summary || level == NMT_detail,
62
"Invalid setting for NativeMemoryTracking (%s)", NativeMemoryTracking);
64
// Memory type is encoded into tracking header as a byte field,
65
// make sure that we don't overflow it.
66
STATIC_ASSERT(mt_number_of_types <= max_jubyte);
68
if (level > NMT_off) {
69
if (!MallocTracker::initialize(level) ||
70
!MemoryFileTracker::Instance::initialize(level) ||
71
!VirtualMemoryTracker::initialize(level)) {
72
assert(false, "NMT initialization failed");
74
log_warning(nmt)("NMT initialization failed. NMT disabled.");
78
if (MallocLimit != nullptr) {
79
warning("MallocLimit will be ignored since NMT is disabled.");
83
NMTPreInit::pre_to_post(level == NMT_off);
85
_tracking_level = level;
87
// Log state right after NMT initialization
88
if (log_is_enabled(Info, nmt)) {
89
LogTarget(Info, nmt) lt;
91
ls.print_cr("NMT initialized: %s", NMTUtil::tracking_level_to_string(_tracking_level));
92
ls.print_cr("Preinit state: ");
93
NMTPreInit::print_state(&ls);
94
MallocLimitHandler::print_on(&ls);
98
// Report during error reporting.
99
void MemTracker::error_report(outputStream* output) {
101
report(true, output, MemReporterBase::default_scale); // just print summary for error case.
102
output->print("Preinit state:");
103
NMTPreInit::print_state(output);
104
MallocLimitHandler::print_on(output);
108
// Report when handling PrintNMTStatistics before VM shutdown.
109
static volatile bool g_final_report_did_run = false;
110
void MemTracker::final_report(outputStream* output) {
111
// This function is called during both error reporting and normal VM exit.
112
// However, it should only ever run once. E.g. if the VM crashes after
113
// printing the final report during normal VM exit, it should not print
114
// the final report again. In addition, it should be guarded from
115
// recursive calls in case NMT reporting itself crashes.
116
if (enabled() && Atomic::cmpxchg(&g_final_report_did_run, false, true) == false) {
117
report(tracking_level() == NMT_summary, output, 1);
121
// Given an unknown pointer, check if it points into a known region; print region if found
122
// and return true; false if not found.
123
bool MemTracker::print_containing_region(const void* p, outputStream* out) {
125
(MallocTracker::print_pointer_information(p, out) ||
126
VirtualMemoryTracker::print_containing_region(p, out));
129
void MemTracker::report(bool summary_only, outputStream* output, size_t scale) {
130
assert(output != nullptr, "No output stream");
131
MemBaseline baseline;
132
baseline.baseline(summary_only);
134
MemSummaryReporter rpt(baseline, output, scale);
137
MemDetailReporter rpt(baseline, output, scale);
139
output->print("Metaspace:");
140
// The basic metaspace report avoids any locking and should be safe to
141
// be called at any time.
142
MetaspaceUtils::print_basic_report(output, scale);
146
void MemTracker::tuning_statistics(outputStream* out) {
148
out->print_cr("Native Memory Tracking Statistics:");
149
out->print_cr("State: %s",
150
NMTUtil::tracking_level_to_string(_tracking_level));
151
if (_tracking_level == NMT_detail) {
152
out->print_cr("Malloc allocation site table size: %d",
153
MallocSiteTable::hash_buckets());
154
out->print_cr(" Tracking stack depth: %d",
155
NMT_TrackingStackDepth);
157
MallocSiteTable::print_tuning_statistics(out);
160
out->print_cr("Preinit state:");
161
NMTPreInit::print_state(out);
162
MallocLimitHandler::print_on(out);