diff --git a/mountpoint-s3/src/cli.rs b/mountpoint-s3/src/cli.rs index 9f0686989..b5538e32b 100644 --- a/mountpoint-s3/src/cli.rs +++ b/mountpoint-s3/src/cli.rs @@ -581,12 +581,25 @@ impl CliArgs { } } +fn configure_malloc() { + unsafe { + println!( + "glibc version: {:?}", + std::ffi::CStr::from_ptr(libc::gnu_get_libc_version()) + ); + // NOTE: M_MMAP_MAX is 65536. With 8MiB allocations it allows up to 512GiB of simultaneously allocated memory via mmap, which should fit for most of the cases. For more info: + // https://github.com/bminor/glibc/blob/release/2.26/master/malloc/malloc.c#L983 + libc::mallopt(libc::M_MMAP_THRESHOLD, 131072); // disable dynamic MMAP_THRESHOLD: https://github.com/bminor/glibc/blob/release/2.26/master/malloc/malloc.c#L1739 + } +} + pub fn main(client_builder: ClientBuilder) -> anyhow::Result<()> where ClientBuilder: FnOnce(&CliArgs) -> anyhow::Result<(Client, Runtime, S3Personality)>, Client: ObjectClient + Clone + Send + Sync + 'static, Runtime: Spawn + Clone + Send + Sync + 'static, { + configure_malloc(); let args = CliArgs::parse(); let successful_mount_msg = format!( "{} is mounted at {}", diff --git a/mountpoint-s3/src/metrics.rs b/mountpoint-s3/src/metrics.rs index 4cc693fb9..fdeb1f983 100644 --- a/mountpoint-s3/src/metrics.rs +++ b/mountpoint-s3/src/metrics.rs @@ -7,6 +7,7 @@ use std::thread::{self, JoinHandle}; use std::time::Duration; use dashmap::DashMap; +use humansize::{format_size, DECIMAL}; use metrics::{Key, Metadata, Recorder}; use sysinfo::{get_current_pid, MemoryRefreshKind, ProcessRefreshKind, ProcessesToUpdate, System}; @@ -44,6 +45,7 @@ pub fn install() -> MetricsSinkHandle { Ok(()) | Err(RecvTimeoutError::Disconnected) => break, Err(RecvTimeoutError::Timeout) => { poll_process_metrics(&mut sys); + poll_malloc_metrics(); inner.publish() } } @@ -52,6 +54,7 @@ pub fn install() -> MetricsSinkHandle { // any new metrics data after the sink shuts down, but we assume a clean shutdown // stops generating new metrics before shutting down the sink. poll_process_metrics(&mut sys); + poll_malloc_metrics(); inner.publish(); }) }; @@ -87,6 +90,24 @@ fn poll_process_metrics(sys: &mut System) { } } +fn poll_malloc_metrics() { + unsafe { + let mallinfo = libc::mallinfo(); + // Space wasted due to fragmentation: `process.mallinfo.arena - process.mallinfo.fordblks` + metrics::gauge!("process.mallinfo.arena").set(mallinfo.arena as f64); /* non-mmapped space allocated from system */ + metrics::gauge!("process.mallinfo.ordblks").set(mallinfo.ordblks as f64); /* number of free chunks */ + metrics::gauge!("process.mallinfo.smblks").set(mallinfo.smblks as f64); /* number of fastbin blocks */ + metrics::gauge!("process.mallinfo.hblks").set(mallinfo.hblks as f64); /* number of mmapped regions */ + metrics::gauge!("process.mallinfo.hblkhd").set(mallinfo.hblkhd as f64); /* space in mmapped regions */ + metrics::gauge!("process.mallinfo.usmblks").set(mallinfo.usmblks as f64); /* always 0, preserved for backwards compatibility */ + metrics::gauge!("process.mallinfo.fsmblks").set(mallinfo.fsmblks as f64); /* space available in freed fastbin blocks */ + metrics::gauge!("process.mallinfo.uordblks").set(mallinfo.uordblks as f64); /* total allocated space */ + metrics::gauge!("process.mallinfo.fordblks").set(mallinfo.fordblks as f64); /* total free space */ + /* top-most, releasable (via malloc_trim) space */ + metrics::gauge!("process.mallinfo.keepcost").set(mallinfo.keepcost as f64); + } +} + #[derive(Debug)] struct MetricsSink { metrics: DashMap,