Coverage Report

Created: 2026-08-06 13:04

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 "load/memtable/memtable_memory_limiter.h"
22
#include "runtime/exec_env.h"
23
#include "runtime/memory/global_memory_arbitrator.h"
24
#include "runtime/memory/jemalloc_control.h"
25
#include "runtime/memory/mem_tracker_limiter.h"
26
#include "runtime/runtime_profile.h"
27
#include "storage/metadata_adder.h"
28
#include "storage/segment/segment_loader.h"
29
#include "storage/tablet/tablet_schema_cache.h"
30
#include "util/mem_info.h"
31
32
namespace doris {
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
    ExecEnv::GetInstance()->rowsets_no_cache_mem_tracker()->set_consumption(
167
0
            MetadataAdder<RowsetMeta>::get_all_rowsets_size());
168
0
    ExecEnv::GetInstance()->segments_no_cache_mem_tracker()->set_consumption(
169
0
            MetadataAdder<segment_v2::Segment>::get_all_segments_estimate_size() -
170
0
            SegmentLoader::instance()->cache_mem_usage());
171
172
    // 4 refresh tracked memory counter
173
0
    std::unordered_map<MemTrackerLimiter::Type, int64_t> type_mem_sum = {
174
0
            {MemTrackerLimiter::Type::GLOBAL, 0},        {MemTrackerLimiter::Type::QUERY, 0},
175
0
            {MemTrackerLimiter::Type::LOAD, 0},          {MemTrackerLimiter::Type::COMPACTION, 0},
176
0
            {MemTrackerLimiter::Type::SCHEMA_CHANGE, 0}, {MemTrackerLimiter::Type::METADATA, 0},
177
0
            {MemTrackerLimiter::Type::CACHE, 0},         {MemTrackerLimiter::Type::OTHER, 0}};
178
    // always ExecEnv::ready(), because Daemon::_stop_background_threads_latch
179
0
    for (auto& group : ExecEnv::GetInstance()->mem_tracker_limiter_pool) {
180
0
        std::lock_guard<std::mutex> l(group.group_lock);
181
0
        for (auto trackerWptr : group.trackers) {
182
0
            auto tracker = trackerWptr.lock();
183
0
            if (tracker != nullptr) {
184
0
                type_mem_sum[tracker->type()] += tracker->consumption();
185
0
            }
186
0
        }
187
0
    }
188
189
0
    int64_t all_tracked_mem_sum = 0;
190
0
    int64_t tasks_trackers_mem_sum = 0;
191
0
    for (auto it : type_mem_sum) {
192
0
        all_tracked_mem_sum += it.second;
193
0
        switch (it.first) {
194
0
        case MemTrackerLimiter::Type::GLOBAL:
195
0
            COUNTER_SET(_global_usage_counter, it.second);
196
0
            memory_global_trackers_sum_bytes
197
0
                    << it.second - memory_global_trackers_sum_bytes.get_value();
198
0
            break;
199
0
        case MemTrackerLimiter::Type::QUERY:
200
0
            COUNTER_SET(_query_usage_counter, it.second);
201
0
            tasks_trackers_mem_sum += it.second;
202
0
            memory_query_trackers_sum_bytes
203
0
                    << it.second - memory_query_trackers_sum_bytes.get_value();
204
0
            break;
205
0
        case MemTrackerLimiter::Type::LOAD:
206
0
            COUNTER_SET(_load_usage_counter, it.second);
207
0
            tasks_trackers_mem_sum += it.second;
208
0
            memory_load_trackers_sum_bytes
209
0
                    << it.second - memory_load_trackers_sum_bytes.get_value();
210
0
            break;
211
0
        case MemTrackerLimiter::Type::COMPACTION:
212
0
            COUNTER_SET(_compaction_usage_counter, it.second);
213
0
            tasks_trackers_mem_sum += it.second;
214
0
            memory_compaction_trackers_sum_bytes
215
0
                    << it.second - memory_compaction_trackers_sum_bytes.get_value();
216
0
            break;
217
0
        case MemTrackerLimiter::Type::SCHEMA_CHANGE:
218
0
            COUNTER_SET(_schema_change_usage_counter, it.second);
219
0
            tasks_trackers_mem_sum += it.second;
220
0
            memory_schema_change_trackers_sum_bytes
221
0
                    << it.second - memory_schema_change_trackers_sum_bytes.get_value();
222
0
            break;
223
0
        case MemTrackerLimiter::Type::METADATA:
224
0
            COUNTER_SET(_metadata_usage_counter, it.second);
225
0
            memory_metadata_trackers_sum_bytes
226
0
                    << it.second - memory_metadata_trackers_sum_bytes.get_value();
227
0
            break;
228
0
        case MemTrackerLimiter::Type::CACHE:
229
0
            COUNTER_SET(_cache_usage_counter, it.second);
230
0
            memory_cache_trackers_sum_bytes
231
0
                    << it.second - memory_cache_trackers_sum_bytes.get_value();
232
0
            break;
233
0
        case MemTrackerLimiter::Type::OTHER:
234
0
            COUNTER_SET(_other_usage_counter, it.second);
235
0
            tasks_trackers_mem_sum += it.second;
236
0
            memory_other_trackers_sum_bytes
237
0
                    << it.second - memory_other_trackers_sum_bytes.get_value();
238
0
        }
239
0
    }
240
241
0
    MemTrackerLimiter::make_type_trackers_profile(global_memory_profile.get(),
242
0
                                                  MemTrackerLimiter::Type::GLOBAL);
243
0
    MemTrackerLimiter::make_type_trackers_profile(metadata_memory_profile.get(),
244
0
                                                  MemTrackerLimiter::Type::METADATA);
245
0
    MemTrackerLimiter::make_type_trackers_profile(cache_memory_profile.get(),
246
0
                                                  MemTrackerLimiter::Type::CACHE);
247
248
0
    MemTrackerLimiter::make_top_consumption_tasks_tracker_profile(top_memory_tasks_profile.get(),
249
0
                                                                  15);
250
251
0
    COUNTER_SET(_tasks_memory_usage_counter, tasks_trackers_mem_sum);
252
0
    memory_all_tasks_memory_bytes << tasks_trackers_mem_sum -
253
0
                                             memory_all_tasks_memory_bytes.get_value();
254
255
0
    COUNTER_SET(_reserved_memory_usage_counter, GlobalMemoryArbitrator::process_reserved_memory());
256
0
    memory_reserved_memory_bytes << GlobalMemoryArbitrator::process_reserved_memory() -
257
0
                                            memory_reserved_memory_bytes.get_value();
258
259
0
    all_tracked_mem_sum += JemallocControl::je_cache_bytes();
260
0
    COUNTER_SET(_jemalloc_cache_usage_counter,
261
0
                static_cast<int64_t>(JemallocControl::je_cache_bytes()));
262
0
    all_tracked_mem_sum += JemallocControl::je_metadata_mem();
263
0
    COUNTER_SET(_jemalloc_metadata_usage_counter,
264
0
                static_cast<int64_t>(JemallocControl::je_metadata_mem()));
265
0
    COUNTER_SET(_jemalloc_memory_usage_counter,
266
0
                _jemalloc_cache_usage_counter->current_value() +
267
0
                        _jemalloc_metadata_usage_counter->current_value());
268
0
    int64_t jvm_heap_bytes = 0;
269
0
    int64_t jvm_non_heap_bytes = 0;
270
    // JvmMetrics only inited when enable_java_support == true, or it is nullptr
271
0
    if (DorisMetrics::instance()->jvm_metrics() != nullptr) {
272
0
        DorisMetrics::instance()->jvm_metrics()->update();
273
0
        jvm_heap_bytes =
274
0
                DorisMetrics::instance()->jvm_metrics()->jvm_heap_size_bytes_committed->value();
275
0
        jvm_non_heap_bytes =
276
0
                DorisMetrics::instance()->jvm_metrics()->jvm_non_heap_size_bytes_committed->value();
277
0
    }
278
279
0
    all_tracked_mem_sum += jvm_heap_bytes + jvm_non_heap_bytes;
280
0
    COUNTER_SET(_jvm_heap_memory_usage_counter, jvm_heap_bytes);
281
0
    COUNTER_SET(_jvm_non_heap_memory_usage_counter, jvm_non_heap_bytes);
282
283
    // Memtable memory is not included in the memory the load tasks. Because actually it is a buffer.
284
0
    COUNTER_SET(_memtable_memory_usage_counter,
285
0
                ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption());
286
0
    all_tracked_mem_sum +=
287
0
            ExecEnv::GetInstance()->memtable_memory_limiter()->mem_tracker()->consumption();
288
289
0
    COUNTER_SET(_tracked_memory_usage_counter, all_tracked_mem_sum);
290
0
    memory_all_tracked_sum_bytes << all_tracked_mem_sum - memory_all_tracked_sum_bytes.get_value();
291
292
    // 5 refresh untracked memory counter
293
0
    int64_t untracked_memory =
294
0
            _process_physical_memory_usage_counter->current_value() - all_tracked_mem_sum;
295
0
    COUNTER_SET(_untracked_memory_usage_counter, untracked_memory);
296
0
    memory_untracked_memory_bytes << untracked_memory - memory_untracked_memory_bytes.get_value();
297
298
    // 6. reset profile
299
0
    _global_memory_profile.set(std::move(global_memory_profile));
300
0
    _metadata_memory_profile.set(std::move(metadata_memory_profile));
301
0
    _cache_memory_profile.set(std::move(cache_memory_profile));
302
0
    _top_memory_tasks_profile.set(std::move(top_memory_tasks_profile));
303
0
}
304
305
0
void MemoryProfile::refresh_tasks_memory_profile() {
306
0
    std::unique_ptr<RuntimeProfile> tasks_memory_profile =
307
0
            std::make_unique<RuntimeProfile>("AllTasksMemorySnapshot");
308
0
    MemTrackerLimiter::make_all_tasks_tracker_profile(tasks_memory_profile.get());
309
0
    _tasks_memory_profile.set(std::move(tasks_memory_profile));
310
0
}
311
312
0
void MemoryProfile::make_memory_profile(RuntimeProfile* profile) const {
313
0
    RuntimeProfile* memory_profile_snapshot = profile->create_child("MemoryProfile", true, false);
314
315
0
    RuntimeProfile* memory_overview_profile =
316
0
            memory_profile_snapshot->create_child(_memory_overview_profile->name(), true, false);
317
0
    memory_overview_profile->merge(_memory_overview_profile.get());
318
319
0
    auto global_memory_version_ptr = _global_memory_profile.get();
320
0
    RuntimeProfile* global_memory_profile =
321
0
            memory_profile_snapshot->create_child(global_memory_version_ptr->name(), true, false);
322
0
    global_memory_profile->merge(global_memory_version_ptr.get());
323
324
0
    auto metadata_memory_version_ptr = _metadata_memory_profile.get();
325
0
    RuntimeProfile* metadata_memory_profile =
326
0
            memory_profile_snapshot->create_child(metadata_memory_version_ptr->name(), true, false);
327
0
    metadata_memory_profile->merge(metadata_memory_version_ptr.get());
328
329
0
    auto cache_memory_version_ptr = _cache_memory_profile.get();
330
0
    RuntimeProfile* cache_memory_profile =
331
0
            memory_profile_snapshot->create_child(cache_memory_version_ptr->name(), true, false);
332
0
    cache_memory_profile->merge(cache_memory_version_ptr.get());
333
334
0
    auto top_memory_tasks_version_ptr = _top_memory_tasks_profile.get();
335
0
    RuntimeProfile* top_memory_tasks_profile = memory_profile_snapshot->create_child(
336
0
            top_memory_tasks_version_ptr->name(), true, false);
337
0
    top_memory_tasks_profile->merge(top_memory_tasks_version_ptr.get());
338
339
0
    auto tasks_memory_version_ptr = _tasks_memory_profile.get();
340
0
    RuntimeProfile* tasks_memory_profile =
341
0
            memory_profile_snapshot->create_child(tasks_memory_version_ptr->name(), true, false);
342
0
    tasks_memory_profile->merge(tasks_memory_version_ptr.get());
343
0
}
344
345
0
int64_t MemoryProfile::query_current_usage() {
346
0
    return memory_query_trackers_sum_bytes.get_value();
347
0
}
348
1
int64_t MemoryProfile::load_current_usage() {
349
1
    return memory_load_trackers_sum_bytes.get_value();
350
1
}
351
0
int64_t MemoryProfile::compaction_current_usage() {
352
0
    return memory_compaction_trackers_sum_bytes.get_value();
353
0
}
354
0
int64_t MemoryProfile::schema_change_current_usage() {
355
0
    return memory_schema_change_trackers_sum_bytes.get_value();
356
0
}
357
0
int64_t MemoryProfile::other_current_usage() {
358
0
    return memory_other_trackers_sum_bytes.get_value();
359
0
}
360
361
4
std::string MemoryProfile::process_memory_detail_str() const {
362
4
    return fmt::format("Process Memory Summary: {}\n, {}\n, {}\n, {}\n, {}\n, {}\n",
363
4
                       GlobalMemoryArbitrator::process_mem_log_str(),
364
4
                       print_memory_overview_profile(), print_global_memory_profile(),
365
4
                       print_metadata_memory_profile(), print_cache_memory_profile(),
366
4
                       print_top_memory_tasks_profile());
367
4
}
368
369
0
void MemoryProfile::print_log_process_usage() {
370
0
    if (_enable_print_log_process_usage) {
371
0
        _enable_print_log_process_usage = false;
372
0
        auto log_str = process_memory_detail_str();
373
        LOG_LONG_STRING(INFO, log_str);
374
0
    }
375
0
}
376
377
} // namespace doris