be/src/runtime/memory/jemalloc_control.h
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 | | #pragma once |
19 | | |
20 | | #include <condition_variable> |
21 | | #include <string> |
22 | | |
23 | | #include "common/logging.h" |
24 | | |
25 | | #ifdef USE_JEMALLOC |
26 | | #include "jemalloc/jemalloc.h" |
27 | | #endif |
28 | | #if !defined(__SANITIZE_ADDRESS__) && !defined(ADDRESS_SANITIZER) && !defined(LEAK_SANITIZER) && \ |
29 | | !defined(THREAD_SANITIZER) && !defined(USE_JEMALLOC) |
30 | | #include <gperftools/malloc_extension.h> |
31 | | #endif |
32 | | |
33 | | namespace doris { |
34 | | #include "common/compile_check_begin.h" |
35 | | |
36 | | class JemallocControl { |
37 | | public: |
38 | 0 | static inline int64_t get_tc_metrics(const std::string& name) { |
39 | 0 | #if !defined(__SANITIZE_ADDRESS__) && !defined(ADDRESS_SANITIZER) && !defined(LEAK_SANITIZER) && \ |
40 | 0 | !defined(THREAD_SANITIZER) && !defined(USE_JEMALLOC) |
41 | 0 | size_t value = 0; |
42 | 0 | MallocExtension::instance()->GetNumericProperty(name.c_str(), &value); |
43 | 0 | return value; |
44 | 0 | #endif |
45 | 0 | return 0; |
46 | 0 | } |
47 | | |
48 | | template <typename T> |
49 | | static inline T get_jemallctl_value(const std::string& name) { |
50 | | #ifdef USE_JEMALLOC |
51 | | T value; |
52 | | size_t value_size = sizeof(T); |
53 | | if (jemallctl(name.c_str(), &value, &value_size, nullptr, 0) != 0) { |
54 | | LOG(WARNING) << fmt::format("Failed, jemallctl get {}", name); |
55 | | } |
56 | | return value; |
57 | | #endif |
58 | | return 0; |
59 | | } |
60 | | |
61 | | template <typename T> |
62 | | static inline void set_jemallctl_value(const std::string& name, T value) { |
63 | | #ifdef USE_JEMALLOC |
64 | | T old_value; |
65 | | size_t old_value_size = sizeof(T); |
66 | | try { |
67 | | int err = jemallctl(name.c_str(), &old_value, &old_value_size, |
68 | | reinterpret_cast<void*>(&value), sizeof(T)); |
69 | | if (err) { |
70 | | LOG(WARNING) << fmt::format("Failed, jemallctl value for {} set to {} (old {})", |
71 | | name, value, old_value); |
72 | | } |
73 | | } catch (...) { |
74 | | LOG(WARNING) << fmt::format("Exception, jemallctl value for {} set to {} (old {})", |
75 | | name, value, old_value); |
76 | | } |
77 | | #endif |
78 | | } |
79 | | |
80 | | static void action_jemallctl(const std::string& name); |
81 | | static int64_t get_je_all_arena_metrics(const std::string& name); |
82 | | static int64_t get_je_all_arena_extents_metrics(int64_t page_size_index, |
83 | | const std::string& extent_type); |
84 | | static void je_purge_all_arena_dirty_pages(); |
85 | | static void je_reset_all_arena_dirty_decay_ms(ssize_t dirty_decay_ms); |
86 | | static void je_decay_all_arena_dirty_pages(); |
87 | | // the limit of `tcache` is the number of pages, not the total number of page bytes. |
88 | | // `tcache` has two cleaning opportunities: 1. the number of memory alloc and releases reaches a certain number, |
89 | | // recycle pages that has not been used for a long time; 2. recycle all `tcache` when the thread exits. |
90 | | // here add a total size limit. |
91 | | // only free the thread cache of the current thread, which will be fast. |
92 | | static void je_thread_tcache_flush(); |
93 | | |
94 | | // Tcmalloc property `generic.total_physical_bytes` records the total length of the virtual memory |
95 | | // obtained by the process malloc, not the physical memory actually used by the process in the OS. |
96 | | static void refresh_allocator_mem(); |
97 | | |
98 | 98.4k | static inline size_t je_cache_bytes() { |
99 | 98.4k | return je_cache_bytes_.load(std::memory_order_relaxed); |
100 | 98.4k | } |
101 | 0 | static inline size_t je_tcache_mem() { return je_tcache_mem_.load(std::memory_order_relaxed); } |
102 | 98.4k | static inline size_t je_metadata_mem() { |
103 | 98.4k | return je_metadata_mem_.load(std::memory_order_relaxed); |
104 | 98.4k | } |
105 | 97.7k | static inline int64_t je_dirty_pages_mem() { |
106 | 97.7k | return je_dirty_pages_mem_.load(std::memory_order_relaxed); |
107 | 97.7k | } |
108 | 97.7k | static inline size_t je_virtual_memory_used() { |
109 | 97.7k | return je_virtual_memory_used_.load(std::memory_order_relaxed); |
110 | 97.7k | } |
111 | | |
112 | | static std::mutex je_purge_dirty_pages_lock; |
113 | | static std::atomic<bool> je_purge_dirty_pages_notify; |
114 | 357 | static void notify_je_purge_dirty_pages() { |
115 | 357 | je_purge_dirty_pages_notify.store(true, std::memory_order_relaxed); |
116 | 357 | } |
117 | | |
118 | | static std::mutex je_reset_dirty_decay_lock; |
119 | | static std::atomic<bool> je_enable_dirty_page; |
120 | | static std::condition_variable je_reset_dirty_decay_cv; |
121 | | static std::atomic<bool> je_reset_dirty_decay_notify; |
122 | 0 | static void notify_je_reset_dirty_decay() { |
123 | 0 | je_reset_dirty_decay_notify.store(true, std::memory_order_relaxed); |
124 | 0 | je_reset_dirty_decay_cv.notify_all(); |
125 | 0 | } |
126 | | |
127 | | private: |
128 | | static std::atomic<int64_t> je_cache_bytes_; |
129 | | static std::atomic<int64_t> je_tcache_mem_; |
130 | | static std::atomic<int64_t> je_metadata_mem_; |
131 | | static std::atomic<int64_t> je_dirty_pages_mem_; |
132 | | static std::atomic<int64_t> je_virtual_memory_used_; |
133 | | }; |
134 | | |
135 | | #include "common/compile_check_end.h" |
136 | | } // namespace doris |