jdk

Форк
0
/
memTracker.cpp 
164 строки · 5.8 Кб
1
/*
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.
5
 *
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.
9
 *
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).
15
 *
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.
19
 *
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
22
 * questions.
23
 *
24
 */
25
#include "precompiled.hpp"
26
#include "jvm.h"
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"
46

47
#ifdef _WINDOWS
48
#include <windows.h>
49
#endif
50

51
NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown;
52

53
MemBaseline MemTracker::_baseline;
54

55
void MemTracker::initialize() {
56
  bool rc = true;
57
  assert(_tracking_level == NMT_unknown, "only call once");
58

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);
63

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);
67

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");
73
      level = NMT_off;
74
      log_warning(nmt)("NMT initialization failed. NMT disabled.");
75
      return;
76
    }
77
  } else {
78
    if (MallocLimit != nullptr) {
79
      warning("MallocLimit will be ignored since NMT is disabled.");
80
    }
81
  }
82

83
  NMTPreInit::pre_to_post(level == NMT_off);
84

85
  _tracking_level = level;
86

87
  // Log state right after NMT initialization
88
  if (log_is_enabled(Info, nmt)) {
89
    LogTarget(Info, nmt) lt;
90
    LogStream ls(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);
95
  }
96
}
97

98
// Report during error reporting.
99
void MemTracker::error_report(outputStream* output) {
100
  if (enabled()) {
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);
105
  }
106
}
107

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);
118
  }
119
}
120

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) {
124
  return enabled() &&
125
      (MallocTracker::print_pointer_information(p, out) ||
126
       VirtualMemoryTracker::print_containing_region(p, out));
127
}
128

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);
133
  if (summary_only) {
134
    MemSummaryReporter rpt(baseline, output, scale);
135
    rpt.report();
136
  } else {
137
    MemDetailReporter rpt(baseline, output, scale);
138
    rpt.report();
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);
143
  }
144
}
145

146
void MemTracker::tuning_statistics(outputStream* out) {
147
  // NMT statistics
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);
156
    out->cr();
157
    MallocSiteTable::print_tuning_statistics(out);
158
    out->cr();
159
  }
160
  out->print_cr("Preinit state:");
161
  NMTPreInit::print_state(out);
162
  MallocLimitHandler::print_on(out);
163
  out->cr();
164
}
165

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.