Skip to content

Commit 0b32ceb

Browse files
authored
Merge pull request #3325 from Pana/chore/bumpJemalloc2
feat: add memory&cpu pprof
2 parents 011fe44 + e7e0561 commit 0b32ceb

File tree

16 files changed

+1219
-99
lines changed

16 files changed

+1219
-99
lines changed

Cargo.lock

Lines changed: 855 additions & 76 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Use workspace section to allow test all cases under root folder (cargo test --all).
21
[workspace]
2+
resolver = "2"
33
exclude = ["tools"]
44
members = [
55
# bins
@@ -111,11 +111,10 @@ members = [
111111
"crates/config",
112112
"crates/cfxcore/types",
113113
"crates/cfxcore/pow",
114-
"crates/cfxcore/errors",
114+
"crates/cfxcore/errors",
115+
"crates/util/mallocator",
115116
]
116117

117-
resolver = "2"
118-
119118
[workspace.package]
120119
version = "3.0.0"
121120
authors = ["Conflux Network"]
@@ -252,6 +251,7 @@ diem-network-address-encryption = { path = "./crates/pos/config/management/netwo
252251
cfx-tasks = { path = "./crates/tasks" }
253252
# eest_types = { path = "./crates/eest_types" }
254253
cfx-config = { path = "./crates/config" }
254+
cfx-mallocator-utils = { path = "./crates/util/mallocator" }
255255

256256
# basics
257257
bytes = "1.9"
@@ -328,9 +328,18 @@ mio = { version = "1.0.4", features = ["os-ext", "net", "os-poll"] }
328328
mio-timer = { git = "https://github.com/Conflux-Chain/mio-timer", rev = "91a02cc" }
329329
mio-misc = { git = "https://github.com/Conflux-Chain/mio-misc", rev = "27ad80f" }
330330
reqwest = "0.12"
331+
axum = "0.8"
332+
mockito = "1.5.0"
331333

332-
# jemallocator
333-
tikv-jemallocator = "0.6"
334+
# mallocator
335+
tikv-jemallocator = { version = "0.6", features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
336+
tikv-jemalloc-ctl = { version = "0.6", features = ["use_std", "stats"] }
337+
tikv-jemalloc-sys = { version = "0.6", features = ["profiling"] }
338+
jemalloc_pprof = { version = "0.8", features = ["symbolize", "flamegraph"] }
339+
# CPU profiling
340+
pprof = { version = "0.15", features = ["flamegraph", "protobuf-codec"] }
341+
tracy-client = "0.18.0"
342+
snmalloc-rs = { version = "0.3.7", features = ["build_cc"] }
334343

335344
# crypto & hash
336345
#fixed-hash = "0.5"

bins/conflux/Cargo.toml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,30 @@ tokio = { workspace = true, features = ["rt"] }
4141
bls-signatures = { workspace = true }
4242
cfx-executor = { workspace = true }
4343
cfx-execute-helper = { workspace = true }
44+
cfx-mallocator-utils = { workspace = true }
4445

4546
[target.'cfg(not(target_env = "msvc"))'.dependencies]
4647
tikv-jemallocator = { workspace = true }
4748

4849
[features]
4950
default = ["jemalloc-global"]
5051
deadlock-detection = ["parking_lot/deadlock_detection"]
51-
jemalloc-global = ["malloc_size_of/jemalloc-global"]
5252
u64-mpt-db-key = ["client/u64_mpt_db_key"]
5353
# According to Rust's feature unification, when a feature is enabled for a dependency in the root package,
5454
# it will be enabled across all paths depending on that package.
5555
# (https://doc.rust-lang.org/cargo/reference/features.html#feature-unification)
5656
blst-portable = ["bls-signatures/blst-portable"]
5757
align_evm = ["cfx-executor/align_evm", "cfx-execute-helper/align_evm"]
58+
# mallocator related features
59+
jemalloc-global = ["malloc_size_of/jemalloc", "cfx-mallocator-utils/jemalloc"]
60+
jemalloc-prof = ["cfx-mallocator-utils/jemalloc", "cfx-mallocator-utils/jemalloc-prof"]
61+
tracy-allocator = ["cfx-mallocator-utils/tracy-allocator"]
62+
# Because jemalloc is default and preferred over snmalloc when both features are
63+
# enabled, `--no-default-features` should be used when enabling snmalloc or
64+
# snmalloc-native.
65+
snmalloc = ["cfx-mallocator-utils/snmalloc"]
66+
snmalloc-native = ["cfx-mallocator-utils/snmalloc-native"]
5867

5968
[dev-dependencies]
6069
tokio = { workspace = true, features = ["full"] }
61-
mockito = "1.5.0"
70+
mockito = { workspace = true }

bins/conflux/src/main.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
// Conflux is free software and distributed under GNU General Public License.
33
// See http://www.gnu.org/licenses/
44

5+
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc-global"))]
6+
#[global_allocator]
7+
static ALLOC: cfx_mallocator_utils::allocator::Allocator =
8+
cfx_mallocator_utils::allocator::new_allocator();
9+
// jemalloc profiling config
10+
#[allow(non_upper_case_globals)]
11+
#[export_name = "malloc_conf"]
12+
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc-prof"))]
13+
pub static malloc_conf: &[u8] =
14+
b"prof:true,prof_active:true,lg_prof_sample:19\0"; // 512kb
15+
516
#[cfg(test)]
617
mod test;
718

crates/client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ cfx-parity-trace-types = { workspace = true }
7979
cfx-tasks = { workspace = true }
8080
cfx-config = { workspace = true }
8181
cfxcore-types = { workspace = true }
82+
cfx-mallocator-utils = { workspace = true }
8283

8384
[dev-dependencies]
8485
criterion = { workspace = true }

crates/client/src/common/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use parking_lot::{Condvar, Mutex};
2121
use rand_08::{prelude::StdRng, rngs::OsRng, SeedableRng};
2222
use threadpool::ThreadPool;
2323

24-
use crate::keylib::KeyPair;
2524
use blockgen::BlockGenerator;
2625
use cfx_executor::machine::{Machine, VmFactory};
2726
use cfx_parameters::genesis::{
@@ -65,6 +64,7 @@ use cfx_config::{parse_config_address_string, Configuration};
6564

6665
use crate::{
6766
accounts::{account_provider, keys_path},
67+
keylib::KeyPair,
6868
rpc::{
6969
extractor::RpcExtractor,
7070
impls::{
@@ -74,6 +74,7 @@ use crate::{
7474
launch_async_rpc_servers, setup_debug_rpc_apis, setup_public_rpc_apis,
7575
},
7676
};
77+
use cfx_mallocator_utils::start_pprf_server;
7778
use cfxcore::consensus::pos_handler::read_initial_nodes_from_file;
7879

7980
pub mod delegate_convert;
@@ -656,9 +657,6 @@ pub fn initialize_not_light_node_modules(
656657
accounts,
657658
));
658659

659-
let task_manager = TaskManager::new(tokio_runtime.handle().clone());
660-
let task_executor = task_manager.executor();
661-
662660
let debug_rpc_http_server = super::rpc::start_http(
663661
conf.local_http_config(),
664662
setup_debug_rpc_apis(
@@ -718,7 +716,8 @@ pub fn initialize_not_light_node_modules(
718716
setup_public_rpc_apis(common_impl, rpc_impl, pubsub, &conf),
719717
)?;
720718

721-
network.start();
719+
let task_manager = TaskManager::new(tokio_runtime.handle().clone());
720+
let task_executor = task_manager.executor();
722721

723722
let eth_rpc_server_handle =
724723
tokio_runtime.block_on(launch_async_rpc_servers(
@@ -730,8 +729,21 @@ pub fn initialize_not_light_node_modules(
730729
conf,
731730
))?;
732731

732+
// start pprf server, which is used to serve the pprof data for heap
733+
// profiling
734+
if let Some(pprf_addr) = conf.raw_conf.profiling_listen_addr.as_ref() {
735+
let pprf_addr = pprf_addr.clone();
736+
let _pprf_server_handle = tokio_runtime.spawn(async move {
737+
if let Err(e) = start_pprf_server(&pprf_addr).await {
738+
eprintln!("Error starting pprof server: {}", e);
739+
}
740+
});
741+
}
742+
733743
metrics::initialize(conf.metrics_config(), task_executor.clone());
734744

745+
network.start();
746+
735747
Ok((
736748
data_man,
737749
pow,

crates/config/src/configuration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ build_config! {
134134
(metrics_output_file, (Option<String>), None)
135135
(metrics_report_interval_ms, (u64), 3_000)
136136
(metrics_prometheus_listen_addr, (Option<String>), None)
137+
(profiling_listen_addr, (Option<String>), None)
137138
(rocksdb_disable_wal, (bool), false)
138139
(txgen_account_count, (usize), 10)
139140

crates/util/malloc_size_of/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ parking_lot = { workspace = true }
1414
smallvec = { workspace = true }
1515

1616
[target.'cfg(not(target_env = "msvc"))'.dependencies]
17-
tikv-jemallocator = { workspace = true }
17+
tikv-jemallocator = { workspace = true, features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
1818

1919
[features]
20-
jemalloc-global = []
20+
jemalloc = []

crates/util/malloc_size_of/src/lib.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010

1111
//! A reduced fork of Firefox's malloc_size_of crate, for bundling with
1212
//! WebRender.
13-
14-
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc-global"))]
15-
use tikv_jemallocator::Jemalloc;
16-
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc-global"))]
17-
#[global_allocator]
18-
static GLOBAL: Jemalloc = Jemalloc;
19-
2013
use cfg_if::cfg_if;
2114
use cfx_types::{
2215
AddressWithSpace, AllChainID, Space, SpaceMap, H160, H256, H512, U256, U512,
@@ -555,7 +548,7 @@ mod usable_size {
555548
HeapSize(heap, 0, ptr) as usize
556549
}
557550

558-
} else if #[cfg(feature = "jemalloc-global")] {
551+
} else if #[cfg(feature = "jemalloc")] {
559552

560553
/// Use of jemalloc usable size C function through jemallocator crate call.
561554
pub unsafe extern "C" fn malloc_usable_size(ptr: *const c_void) -> usize {

crates/util/mallocator/Cargo.toml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[package]
2+
name = "cfx-mallocator-utils"
3+
version.workspace = true
4+
authors.workspace = true
5+
description.workspace = true
6+
documentation.workspace = true
7+
homepage.workspace = true
8+
keywords.workspace = true
9+
repository.workspace = true
10+
license-file.workspace = true
11+
edition.workspace = true
12+
13+
[dependencies]
14+
chrono = { workspace = true }
15+
jemalloc_pprof = { workspace = true }
16+
pprof = { workspace = true }
17+
log = { workspace = true }
18+
tokio = { workspace = true }
19+
axum = { workspace = true }
20+
cfg-if = { workspace = true }
21+
tracy-client = { workspace = true, optional = true, features = ["demangle"] }
22+
23+
[target.'cfg(unix)'.dependencies]
24+
tikv-jemallocator = { workspace = true, optional = true }
25+
snmalloc-rs = { workspace = true, optional = true }
26+
libc = "0.2"
27+
28+
[features]
29+
jemalloc = ["dep:tikv-jemallocator"]
30+
31+
# Enables jemalloc profiling features
32+
jemalloc-prof = ["jemalloc", "tikv-jemallocator?/profiling"]
33+
34+
# Wraps the selected allocator in the tracy profiling allocator
35+
tracy-allocator = ["dep:tracy-client"]
36+
37+
snmalloc = ["dep:snmalloc-rs"]
38+
39+
# Enables the snmalloc-rs `native-cpu` feature, which optimizes snmalloc for the
40+
# native CPU of the host machine. Not sure why this feature is not derived from
41+
# RUSTFLAGS or enabled when `target-cpu=native`.
42+
snmalloc-native = ["snmalloc", "snmalloc-rs/native-cpu"]

0 commit comments

Comments
 (0)