mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-16 12:28:24 +00:00
Tune GNU malloc (#2299)
## Issue Addressed NA ## Proposed Changes Modify the configuration of [GNU malloc](https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html) to reduce memory footprint. - Set `M_ARENA_MAX` to 4. - This reduces memory fragmentation at the cost of contention between threads. - Set `M_MMAP_THRESHOLD` to 2mb - This means that any allocation >= 2mb is allocated via an anonymous mmap, instead of on the heap/arena. This reduces memory fragmentation since we don't need to keep growing the heap to find big contiguous slabs of free memory. - ~~Run `malloc_trim` every 60 seconds.~~ - ~~This shaves unused memory from the top of the heap, preventing the heap from constantly growing.~~ - Removed, see: https://github.com/sigp/lighthouse/pull/2299#issuecomment-825322646 *Note: this only provides memory savings on the Linux (glibc) platform.* ## Additional Info I'm going to close #2288 in favor of this for the following reasons: - I've managed to get the memory footprint *smaller* here than with jemalloc. - This PR seems to be less of a dramatic change than bringing in the jemalloc dep. - The changes in this PR are strictly runtime changes, so we can create CLI flags which disable them completely. Since this change is wide-reaching and complex, it's nice to have an easy "escape hatch" if there are undesired consequences. ## TODO - [x] Allow configuration via CLI flags - [x] Test on Mac - [x] Test on RasPi. - [x] Determine if GNU malloc is present? - I'm not quite sure how to detect for glibc.. This issue suggests we can't really: https://github.com/rust-lang/rust/issues/33244 - [x] Make a clear argument regarding the affect of this on CPU utilization. - [x] Test with higher `M_ARENA_MAX` values. - [x] Test with longer trim intervals - [x] Add some stats about memory savings - [x] Remove `malloc_trim` calls & code
This commit is contained in:
@@ -2,10 +2,12 @@ mod metrics;
|
||||
|
||||
use beacon_node::{get_eth2_network_config, ProductionBeaconNode};
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use clap_utils::flags::DISABLE_MALLOC_TUNING_FLAG;
|
||||
use env_logger::{Builder, Env};
|
||||
use environment::EnvironmentBuilder;
|
||||
use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK};
|
||||
use lighthouse_version::VERSION;
|
||||
use malloc_utils::configure_memory_allocator;
|
||||
use slog::{crit, info, warn};
|
||||
use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
@@ -144,6 +146,16 @@ fn main() {
|
||||
Used for testing only, DO NOT USE IN PRODUCTION.")
|
||||
.global(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(DISABLE_MALLOC_TUNING_FLAG)
|
||||
.long(DISABLE_MALLOC_TUNING_FLAG)
|
||||
.help(
|
||||
"If present, do not configure the system allocator. Providing this flag will \
|
||||
generally increase memory usage, it should only be provided when debugging \
|
||||
specific memory allocation issues."
|
||||
)
|
||||
.global(true),
|
||||
)
|
||||
.subcommand(beacon_node::cli_app())
|
||||
.subcommand(boot_node::cli_app())
|
||||
.subcommand(validator_client::cli_app())
|
||||
@@ -151,6 +163,19 @@ fn main() {
|
||||
.subcommand(remote_signer::cli_app())
|
||||
.get_matches();
|
||||
|
||||
// Configure the allocator early in the process, before it has the chance to use the default values for
|
||||
// anything important.
|
||||
if !matches.is_present(DISABLE_MALLOC_TUNING_FLAG) {
|
||||
if let Err(e) = configure_memory_allocator() {
|
||||
eprintln!(
|
||||
"Unable to configure the memory allocator: {} \n\
|
||||
Try providing the --{} flag",
|
||||
e, DISABLE_MALLOC_TUNING_FLAG
|
||||
);
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Debugging output for libp2p and external crates.
|
||||
if matches.is_present("env_log") {
|
||||
Builder::from_env(Env::default()).init();
|
||||
|
||||
Reference in New Issue
Block a user