Coverage Report

Created: 2026-03-16 21:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/runtime/memory/memory_profile.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "runtime/memory/memory_profile.h"
19
20
#include "bvar/reducer.h"
21
#include "runtime/exec_env.h"
22
#include "runtime/memory/global_memory_arbitrator.h"
23
#include "runtime/memory/jemalloc_control.h"
24
#include "runtime/memory/mem_tracker_limiter.h"
25
#include "runtime/runtime_profile.h"
26
#include "storage/cache/schema_cache.h"
27
#include "storage/metadata_adder.h"
28
#include "storage/tablet/tablet_schema_cache.h"
29
#include "util/mem_info.h"
30
31
namespace doris {
32
#include "common/compile_check_begin.h"
33
34
static bvar::Adder<int64_t> memory_all_tracked_sum_bytes("memory_all_tracked_sum_bytes");
35
static bvar::Adder<int64_t> memory_global_trackers_sum_bytes("memory_global_trackers_sum_bytes");
36
static bvar::Adder<int64_t> memory_metadata_trackers_sum_bytes(
37
        "memory_metadata_trackers_sum_bytes");
38
static bvar::Adder<int64_t> memory_cache_trackers_sum_bytes("memory_cache_trackers_sum_bytes");
39
static bvar::Adder<int64_t> memory_query_trackers_sum_bytes("memory_query_trackers_sum_bytes");
40
static bvar::Adder<int64_t> memory_load_trackers_sum_bytes("memory_load_trackers_sum_bytes");
41
static bvar::Adder<int64_t> memory_compaction_trackers_sum_bytes(
42
        "memory_compaction_trackers_sum_bytes");
43
static bvar::Adder<int64_t> memory_schema_change_trackers_sum_bytes(
44
        "memory_schema_change_trackers_sum_bytes");
45
static bvar::Adder<int64_t> memory_other_trackers_sum_bytes("memory_other_trackers_sum_bytes");
46
static bvar::Adder<int64_t> memory_reserved_memory_bytes("memory_reserved_memory_bytes");
47
static bvar::Adder<int64_t> memory_all_tasks_memory_bytes("memory_all_tasks_memory_bytes");
48
static bvar::Adder<int64_t> memory_untracked_memory_bytes("memory_untracked_memory_bytes");
49
50
1
MemoryProfile::MemoryProfile() {
51
1
#ifdef ADDRESS_SANITIZER
52
1
    _memory_overview_profile = std::make_unique<RuntimeProfile>("[ASAN]MemoryOverviewSnapshot");
53
#else
54
    _memory_overview_profile = std::make_unique<RuntimeProfile>("MemoryOverviewSnapshot");
55
#endif
56
1
    _global_memory_profile.set(std::make_unique<RuntimeProfile>("GlobalMemorySnapshot"));
57
1
    _metadata_memory_profile.set(std::make_unique<RuntimeProfile>("MetadataMemorySnapshot"));
58
1
    _cache_memory_profile.set(std::make_unique<RuntimeProfile>("CacheMemorySnapshot"));
59
1
    _top_memory_tasks_profile.set(std::make_unique<RuntimeProfile>("TopMemoryTasksSnapshot"));
60
1
    _tasks_memory_profile.set(std::make_unique<RuntimeProfile>("TasksMemorySnapshot"));
61
1
    init_memory_overview_counter();
62
1
}
63
64
1
void MemoryProfile::init_memory_overview_counter() {
65
1
    RuntimeProfile* untracked_memory_profile =
66
1
            _memory_overview_profile->create_child("UntrackedMemory", true, false);
67
1
    RuntimeProfile* tracked_memory_profile =
68
1
            _memory_overview_profile->create_child("TrackedMemory", true, false);
69
1
    RuntimeProfile* tasks_memory_overview_profile =
70
1
            tracked_memory_profile->create_child("TasksMemory", true, false);
71
1
    RuntimeProfile* tasks_memory_overview_details_profile =
72
1
            tasks_memory_overview_profile->create_child("Details", true, false);
73
74
1
    RuntimeProfile* memtable_overview_profile =
75
1
            tracked_memory_profile->create_child("MemtableMemory", true, false);
76
77
1
    RuntimeProfile* global_memory_overview_profile =
78
1
            tracked_memory_profile->create_child("GlobalMemory", true, false);
79
80
1
    RuntimeProfile* jvm_memory_overview_profile =
81
1
            tracked_memory_profile->create_child("JvmMemory", true, false);
82
1
    RuntimeProfile* metadata_memory_overview_profile =
83
1
            tracked_memory_profile->create_child("MetadataMemory", true, false);
84
1
    RuntimeProfile* cache_memory_overview_profile =
85
1
            tracked_memory_profile->create_child("CacheMemory", true, false);
86
1
    RuntimeProfile* jemalloc_memory_profile =
87
1
            tracked_memory_profile->create_child("JemallocMemory", true, false);
88
1
    RuntimeProfile* jemalloc_memory_details_profile =
89
1
            jemalloc_memory_profile->create_child("Details", true, false);
90
91
    // 1 add process memory counter
92
1
    _process_physical_memory_usage_counter = _memory_overview_profile->AddHighWaterMarkCounter(
93
1
            "PhysicalMemory(VmRSS)", TUnit::BYTES);
94
1
    _process_virtual_memory_usage_counter = _memory_overview_profile->AddHighWaterMarkCounter(
95
1
            "VirtualMemory(VmSize)", TUnit::BYTES);
96
97
    // 2 add untracked/tracked memory counter
98
1
    _untracked_memory_usage_counter =
99
1
            untracked_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
100
1
    _tracked_memory_usage_counter =
101
1
            tracked_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
102
103
    // 3 add Jemalloc memory counter
104
1
    _jemalloc_memory_usage_counter =
105
1
            jemalloc_memory_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
106
1
    _jemalloc_cache_usage_counter =
107
1
            jemalloc_memory_details_profile->AddHighWaterMarkCounter("Cache", TUnit::BYTES);
108
1
    _jemalloc_metadata_usage_counter =
109
1
            jemalloc_memory_details_profile->AddHighWaterMarkCounter("Metadata", TUnit::BYTES);
110
111
    // 4 add global/metadata/cache/Jvm memory counter
112
1
    _global_usage_counter =
113
1
            global_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
114
1
    _metadata_usage_counter =
115
1
            metadata_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
116
1
    _cache_usage_counter =
117
1
            cache_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
118
1
    _jvm_heap_memory_usage_counter =
119
1
            jvm_memory_overview_profile->AddHighWaterMarkCounter("HeapMemory", TUnit::BYTES);
120
1
    _jvm_non_heap_memory_usage_counter =
121
1
            jvm_memory_overview_profile->AddHighWaterMarkCounter("NonHeapMemory", TUnit::BYTES);
122
123
    // 5 add tasks memory counter
124
1
    _tasks_memory_usage_counter =
125
1
            tasks_memory_overview_profile->AddHighWaterMarkCounter("Memory", TUnit::BYTES);
126
    // Reserved memory is the sum of all task reserved memory, is duplicated with all task memory counter.
127
1
    _reserved_memory_usage_counter = tasks_memory_overview_profile->AddHighWaterMarkCounter(
128
1
            "ReservedMemory", TUnit::BYTES, "Memory", 1);
129
130
    // 6 add memtable memory counter
131
1
    _memtable_memory_usage_counter =
132
1
            memtable_overview_profile->AddHighWaterMarkCounter("MemtableMemory", TUnit::BYTES);
133
1
    _query_usage_counter =
134
1
            tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Query", TUnit::BYTES);
135
1
    _load_usage_counter =
136
1
            tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Load", TUnit::BYTES);
137
1
    _compaction_usage_counter = tasks_memory_overview_details_profile->AddHighWaterMarkCounter(
138
1
            "Compaction", TUnit::BYTES);
139
1
    _schema_change_usage_counter = tasks_memory_overview_details_profile->AddHighWaterMarkCounter(
140
1
            "SchemaChange", TUnit::BYTES);
141
1
    _other_usage_counter =
142
1
            tasks_memory_overview_details_profile->AddHighWaterMarkCounter("Other", TUnit::BYTES);
143
1
}
144
145
0
void MemoryProfile::refresh_memory_overview_profile() {
146
    // 1 create profile
147
0
    std::unique_ptr<RuntimeProfile> global_memory_profile =
148
0
            std::make_unique<RuntimeProfile>("GlobalMemorySnapshot");
149
0
    std::unique_ptr<RuntimeProfile> metadata_memory_profile =
150
0
            std::make_unique<RuntimeProfile>("MetadataMemorySnapshot");
151
0
    std::unique_ptr<RuntimeProfile> cache_memory_profile =
152
0
            std::make_unique<RuntimeProfile>("CacheMemorySnapshot");
153
0
    std::unique_ptr<RuntimeProfile> top_memory_tasks_profile =
154
0
            std::make_unique<RuntimeProfile>("TopMemoryTasksSnapshot");
155
156
    // 2 refresh process memory counter
157
0
    COUNTER_SET(_process_physical_memory_usage_counter,
158
0
                PerfCounters::get_vm_rss()); // from /proc VmRSS VmHWM
159
0
    COUNTER_SET(_process_virtual_memory_usage_counter,
160
0
                PerfCounters::get_vm_size()); // from /proc VmSize VmPeak
161
162
    // 2 refresh metadata memory tracker
163
0
    ExecEnv::GetInstance()->tablets_no_cache_mem_tracker()->set_consumption(
164
0
            MetadataAdder<TabletMeta>::get_all_tablets_size() -
165
0
            TabletSchemaCache::instance()->value_mem_consumption() -
166
0
            SchemaCache::instance()->value_mem_consumption());
167
0
    ExecEnv::GetInstance()->rowsets_no_cache_mem_tracker()->set_consumption(
168
0
            MetadataAdder<RowsetMeta>::get_all_rowsets_size());
169
0
    ExecEnv::GetInstance()->segments_no_cache_mem_tracker()->set_consumption(
170
0
            MetadataAdder<segment_v2::Segment>::get_all_segments_estimate_size() -
171
0
            SegmentLoader::instance()->cache_mem_usage());
172
173
    // 4 refresh tracked memory counter
174
0
    std::unordered_map<MemTrackerLimiter::Type, int64_t> type_mem_sum = {
175
0
            {MemTrackerLimiter::Type::GLOBAL, 0},        {MemTrackerLimiter::Type::QUERY, 0},
176
0
            {MemTrackerLimiter::Type::LOAD, 0},          {MemTrackerLimiter::Type::COMPACTION, 0},
177
0
            {MemTrackerLimiter::Type::SCHEMA_CHANGE, 0}, {MemTrackerLimiter::Type::METADATA, 0},
178
0
            {MemTrackerLimiter::Type::CACHE, 0},         {MemTrackerLimiter::Type::OTHER, 0}};
179
    // always ExecEnv::ready(), because Daemon::_stop_background_threads_latch
180
0
    for (auto& group : ExecEnv::GetInstance()->mem_tracker_limiter_pool) {
181
0
        std::lock_guard<std::mutex> l(group.group_lock);
182
0
        for (auto trackerWptr : group.trackers) {
183
0
            auto tracker = trackerWptr.lock();
184
0
            if (tracker != nullptr) {
185
0
                type_mem_sum[tracker->type()] += tracker->consumption();
186
0
            }
187
0
        }
188
0
    }
189
190
0
    int64_t all_tracked_mem_sum = 0;
191
0
    int64_t tasks_trackers_mem_sum = 0;
192
0
    for (auto it : type_mem_sum) {
193
0
        all_tracked_mem_sum += it.second;
194
0
        switch (it.first) {
195
0
        case MemTrackerLimiter::Type::GLOBAL:
196
0
            COUNTER_SET(_global_usage_counter, it.second);
197
0
            memory_global_trackers_sum_bytes
198
0
                    << it.second - memory_global_trackers_sum_bytes.get_value();
199
0
            break;
200
0
        case MemTrackerLimiter::Type::QUERY:
201
0
            COUNTER_SET(_query_usage_counter, it.second);
202
0
            tasks_trackers_mem_sum += it.second;
203
0
            memory_query_trackers_sum_bytes
204
0
                    << it.second - memory_query_trackers_sum_bytes.get_value();
205
0
            break;
206
0
        case MemTrackerLimiter::Type::LOAD:
207
0
            COUNTER_SET(_load_usage_counter, it.second);
208
0
            tasks_trackers_mem_sum += it.second;
209
0
            memory_load_trackers_sum_bytes
210
0
                    << it.second - memory_load_trackers_sum_bytes.get_value();
211
0
            break;
212
0
        case MemTrackerLimiter::Type::COMPACTION:
213
0
            COUNTER_SET(_compaction_usage_counter, it.second);
214
0
            tasks_trackers_mem_sum += it.second;
215
0
            memory_compaction_trackers_sum_bytes
216
0
                    << it.second - memory_compaction_trackers_sum_bytes.get_value();
217
0
            break;
218
0
        case MemTrackerLimiter::Type::SCHEMA_CHANGE:
219
0
            COUNTER_SET(_schema_change_usage_counter, it.second);
220
0
            tasks_trackers_mem_sum += it.second;
221
0
            memory_schema_change_trackers_sum_bytes
222
0
                    << it.second - memory_schema_change_trackers_sum_bytes.get_value();
223
0
            break;
224
0
        case MemTrackerLimiter::Type::METADATA:
225
0
            COUNTER_SET(_metadata_usage_counter, it.second);
226
0
            memory_metadata_trackers_sum_bytes
227
0
                    << it.second - memory_metadata_trackers_sum_bytes.get_value();
228
0
            break;
229
0
        case MemTrackerLimiter::Type::CACHE:
230
0
            COUNTER_SET(_cache_usage_counter, it.second);
231
0
            memory_cache_trackers_sum_bytes
232
0
                    << it.second - memory_cache_trackers_sum_bytes.get_value();
233
0
            break;
234
0
        case MemTrackerLimiter::Type::OTHER:
235
0
            COUNTER_SET(_other_usage_counter, it.second);
236
0
            tasks_trackers_mem_sum += it.second;
237
0
            memory_other_trackers_sum_bytes
238
0
                    << it.second - memory_other_trackers_sum_bytes.get_value();
239
0
        }
240
0
    }
241
242
0
    MemTrackerLimiter::make_type_trackers_profile(global_memory_profile.get(),
243
0
                                                  MemTrackerLimiter::Type::GLOBAL);
244
0
    MemTrackerLimiter::make_type_trackers_profile(metadata_memory_profile.get(),
245
0
                                                  MemTrackerLimiter::Type::METADATA);
246
0
    MemTrackerLimiter::make_type_trackers_profile(cache_memory_profile.get(),
247
0
                                                  MemTrackerLimiter::Type::CACHE);
248
249
0
    MemTrackerLimiter::make_top_consumption_tasks_tracker_profile(top_memory_tasks_profile.get(),
250
0
                                                                  15);
251
252
0
    COUNTER_SET(_tasks_memory_usage_counter, tasks_trackers_mem_sum);
253
0
    memory_all_tasks_memory_bytes << tasks_trackers_mem_sum -
254
0
                                             memory_all_tasks_memory_bytes.get_value();
255
256
0
    COUNTER_SET(_reserved_memory_usage_counter, GlobalMemoryArbitrator::process_reserved_memory());
257
0
    memory_reserved_memory_bytes << GlobalMemoryArbitrator::process_reserved_memory() -
258
0
                                            memory_reserved_memory_bytes.get_value();
259
260
0
    all_tracked_mem_sum += JemallocControl::je_cache_bytes();
261
0
    COUNTER_SET(_jemalloc_cache_usage_counter,
262
0
                static_cast<int64_t>(JemallocControl::je_cache_bytes()));
263
0
    all_tracked_mem_sum += JemallocControl::je_metadata_mem();
264
0
    COUNTER_SET(_jemalloc_metadata_usage_counter,
265
0
                static_cast<int64_t>(JemallocControl::je_metadata_mem()));
266
0
    COUNTER_SET(_jemalloc_memory_usage_counter,
267
0
                _jemalloc_cache_usage_counter->current_value() +
268
0
                        _jemalloc_metadata_usage_counter->current_value());
269
0
    int64_t jvm_heap_bytes = 0;
270
0
    int64_t jvm_non_heap_bytes = 0;
271
    // JvmMetrics only inited when enable_java_support == true, or it is nullptr
272
0
    if (DorisMetrics::instance()->jvm_metrics() != nullptr) {
273
0
        DorisMetrics::instance()->jvm_metrics()->update();
274
0
        jvm_heap_bytes =
275
0
                DorisMetrics::instance()->jvm_metrics()->jvm_heap_size_bytes_committed->value();
276
0
        jvm_non_heap_bytes =
277
0
                DorisMetrics::instance()->jvm_metrics()->jvm_non_heap_size_bytes_committed->value();
278
0
    }
279
280
0
    all_tracked_mem_sum += jvm_heap_bytes + jvm_non_heap_bytes;
281
0
    COUNTER_SET(_jvm_heap_memory_usage_counter, jvm_heap_bytes);
282
0
    COUNTER_SET(_jvm_non_heap_memory_usage_counter, jvm_non_heap_bytes);
283
284
    // Memtable memory is not included in the memory the load tasks. Because actually it is a buffer.
285
0
    COUNTER_SET(_memtable_memory_usage_counter,
286
0
                ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption());
287
0
    all_tracked_mem_sum +=
288
0
            ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption();
289
290
0
    COUNTER_SET(_tracked_memory_usage_counter, all_tracked_mem_sum);
291
0
    memory_all_tracked_sum_bytes << all_tracked_mem_sum - memory_all_tracked_sum_bytes.get_value();
292
293
    // 5 refresh untracked memory counter
294
0
    int64_t untracked_memory =
295
0
            _process_physical_memory_usage_counter->current_value() - all_tracked_mem_sum;
296
0
    COUNTER_SET(_untracked_memory_usage_counter, untracked_memory);
297
0
    memory_untracked_memory_bytes << untracked_memory - memory_untracked_memory_bytes.get_value();
298
299
    // 6. reset profile
300
0
    _global_memory_profile.set(std::move(global_memory_profile));
301
0
    _metadata_memory_profile.set(std::move(metadata_memory_profile));
302
0
    _cache_memory_profile.set(std::move(cache_memory_profile));
303
0
    _top_memory_tasks_profile.set(std::move(top_memory_tasks_profile));
304
0
}
305
306
0
void MemoryProfile::refresh_tasks_memory_profile() {
307
0
    std::unique_ptr<RuntimeProfile> tasks_memory_profile =
308
0
            std::make_unique<RuntimeProfile>("AllTasksMemorySnapshot");
309
0
    MemTrackerLimiter::make_all_tasks_tracker_profile(tasks_memory_profile.get());
310
0
    _tasks_memory_profile.set(std::move(tasks_memory_profile));
311
0
}
312
313
0
void MemoryProfile::make_memory_profile(RuntimeProfile* profile) const {
314
0
    RuntimeProfile* memory_profile_snapshot = profile->create_child("MemoryProfile", true, false);
315
316
0
    RuntimeProfile* memory_overview_profile =
317
0
            memory_profile_snapshot->create_child(_memory_overview_profile->name(), true, false);
318
0
    memory_overview_profile->merge(_memory_overview_profile.get());
319
320
0
    auto global_memory_version_ptr = _global_memory_profile.get();
321
0
    RuntimeProfile* global_memory_profile =
322
0
            memory_profile_snapshot->create_child(global_memory_version_ptr->name(), true, false);
323
0
    global_memory_profile->merge(global_memory_version_ptr.get());
324
325
0
    auto metadata_memory_version_ptr = _metadata_memory_profile.get();
326
0
    RuntimeProfile* metadata_memory_profile =
327
0
            memory_profile_snapshot->create_child(metadata_memory_version_ptr->name(), true, false);
328
0
    metadata_memory_profile->merge(metadata_memory_version_ptr.get());
329
330
0
    auto cache_memory_version_ptr = _cache_memory_profile.get();
331
0
    RuntimeProfile* cache_memory_profile =
332
0
            memory_profile_snapshot->create_child(cache_memory_version_ptr->name(), true, false);
333
0
    cache_memory_profile->merge(cache_memory_version_ptr.get());
334
335
0
    auto top_memory_tasks_version_ptr = _top_memory_tasks_profile.get();
336
0
    RuntimeProfile* top_memory_tasks_profile = memory_profile_snapshot->create_child(
337
0
            top_memory_tasks_version_ptr->name(), true, false);
338
0
    top_memory_tasks_profile->merge(top_memory_tasks_version_ptr.get());
339
340
0
    auto tasks_memory_version_ptr = _tasks_memory_profile.get();
341
0
    RuntimeProfile* tasks_memory_profile =
342
0
            memory_profile_snapshot->create_child(tasks_memory_version_ptr->name(), true, false);
343
0
    tasks_memory_profile->merge(tasks_memory_version_ptr.get());
344
0
}
345
346
0
int64_t MemoryProfile::query_current_usage() {
347
0
    return memory_query_trackers_sum_bytes.get_value();
348
0
}
349
21
int64_t MemoryProfile::load_current_usage() {
350
21
    return memory_load_trackers_sum_bytes.get_value();
351
21
}
352
0
int64_t MemoryProfile::compaction_current_usage() {
353
0
    return memory_compaction_trackers_sum_bytes.get_value();
354
0
}
355
0
int64_t MemoryProfile::schema_change_current_usage() {
356
0
    return memory_schema_change_trackers_sum_bytes.get_value();
357
0
}
358
0
int64_t MemoryProfile::other_current_usage() {
359
0
    return memory_other_trackers_sum_bytes.get_value();
360
0
}
361
362
2
std::string MemoryProfile::process_memory_detail_str() const {
363
2
    return fmt::format("Process Memory Summary: {}\n, {}\n, {}\n, {}\n, {}\n, {}\n",
364
2
                       GlobalMemoryArbitrator::process_mem_log_str(),
365
2
                       print_memory_overview_profile(), print_global_memory_profile(),
366
2
                       print_metadata_memory_profile(), print_cache_memory_profile(),
367
2
                       print_top_memory_tasks_profile());
368
2
}
369
370
0
void MemoryProfile::print_log_process_usage() {
371
0
    if (_enable_print_log_process_usage) {
372
0
        _enable_print_log_process_usage = false;
373
0
        auto log_str = process_memory_detail_str();
374
        LOG_LONG_STRING(INFO, log_str);
375
0
    }
376
0
}
377
378
#include "common/compile_check_end.h"
379
} // namespace doris