bug: switch over to procfs for linux mem usage (#547)
Swap to manually calculating the mem total and usage via procfs. The usage calculation is now: total - (free + cached + buffers + slab_reclaimable - shmem) This follows the same usage calculation as htop. See the PR for more details.
This commit is contained in:
parent
4e07a28e17
commit
7f24e62867
|
@ -12,7 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
## Bug Fixes
|
||||
|
||||
- [#542](https://github.com/ClementTsang/bottom/pull/542): Fixes missing config options in the default generated config file.
|
||||
- [#545](https://github.com/ClementTsang/bottom/pull/545): Fixes inaccurate memory usage/totals in macOS and Linux.
|
||||
- [#545](https://github.com/ClementTsang/bottom/pull/545): Fixes inaccurate memory usage/totals in macOS and Linux, switch unit to binary prefix.
|
||||
|
||||
## Changes
|
||||
|
||||
- [#547](https://github.com/ClementTsang/bottom/pull/547): Switch memory usage calculation to match htop.
|
||||
|
||||
## [0.6.2] - 2021-06-26
|
||||
|
||||
|
|
|
@ -28,3 +28,13 @@ Note that key bindings are generally case-sensitive.
|
|||
| Binding | Action |
|
||||
| ------------ | -------------------------------------------------------------- |
|
||||
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
|
||||
|
||||
## Calculations
|
||||
|
||||
Memory usage is calculated using the following formula based on values from `/proc/meminfo` (based on [htop's implementation](https://github.com/htop-dev/htop/blob/976c6123f41492aaf613b9d172eef1842fb7b0a3/linux/LinuxProcessList.c#L1584)):
|
||||
|
||||
```
|
||||
MemTotal - MemFree - Buffers - (Cached + SReclaimable - Shmem)
|
||||
```
|
||||
|
||||
You can find more info on `/proc/meminfo` and its fields [here](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo).
|
||||
|
|
|
@ -23,27 +23,38 @@ pub async fn get_mem_data(
|
|||
}
|
||||
|
||||
pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
||||
let memory = heim::memory::memory().await?;
|
||||
|
||||
let (mem_total_in_kib, mem_used_in_kib) = {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
use heim::memory::os::linux::MemoryExt;
|
||||
use heim::units::information::kilobyte;
|
||||
let mem_info = procfs::Meminfo::new()?;
|
||||
|
||||
// For Linux, the "kilobyte" value in the .total call is actually kibibytes - see
|
||||
// https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo
|
||||
// Let's preface this by saying that memory usage calculations are... not straightforward.
|
||||
// There are conflicting implementations everywhere.
|
||||
//
|
||||
// Heim parses this as kilobytes (https://github.com/heim-rs/heim/blob/master/heim-memory/src/sys/linux/memory.rs#L82)
|
||||
// even though it probably shouldn't...
|
||||
// Now that we've added this preface (mainly for future reference), the current implementation below for usage
|
||||
// is based on htop's calculation formula. See
|
||||
// https://github.com/htop-dev/htop/blob/976c6123f41492aaf613b9d172eef1842fb7b0a3/linux/LinuxProcessList.c#L1584
|
||||
// for implementation details as of writing.
|
||||
//
|
||||
// Another implementation, commonly used in other things, is to skip the shmem part of the calculation,
|
||||
// which matches gopsutil and stuff like free.
|
||||
|
||||
(
|
||||
memory.total().get::<kilobyte>(),
|
||||
memory.used().get::<kilobyte>(),
|
||||
)
|
||||
let total = mem_info.mem_total / 1024;
|
||||
let cached_mem =
|
||||
mem_info.cached + mem_info.s_reclaimable.unwrap_or(0) - mem_info.shmem.unwrap_or(0);
|
||||
let used_diff = (mem_info.mem_free + cached_mem + mem_info.buffers) / 1024;
|
||||
let used = if total >= used_diff {
|
||||
total - used_diff
|
||||
} else {
|
||||
total - mem_info.mem_free
|
||||
};
|
||||
|
||||
(total, used)
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let memory = heim::memory::memory().await?;
|
||||
|
||||
use heim::memory::os::macos::MemoryExt;
|
||||
use heim::units::information::kibibyte;
|
||||
(
|
||||
|
@ -53,6 +64,8 @@ pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
|||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let memory = heim::memory::memory().await?;
|
||||
|
||||
use heim::units::information::kibibyte;
|
||||
let mem_total_in_kib = memory.total().get::<kibibyte>();
|
||||
(
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] {
|
||||
pub mod heim;
|
||||
pub use self::heim::*;
|
||||
pub mod general;
|
||||
pub use self::general::*;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue