# What does top KiB Mem percent data mean?

When I use top, the memory data is displayed in the overview area as follows：

``````KiB Mem : 16092836 total,   143168 free, 11005184 used,  4944484 buff/cache
``````

Then I use m (interactive command) to switch the memory data display mode：

``````KiB Mem : 88.7/16092836 [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||         ]
``````

My question is: the result of `100*used/total` is `68.3856`, how was the `88.7` calculated?

The percentage is equivalent to `100*used/total`, as you imagined.

The percentage is `100*(1-available/total)`, confusingly different from `100*used/total`.

Here, "available" means the same as shown in `free`.

# Reference manual

The behavior is documented in the reference manual.

In the alternate memory display modes, two abbreviated summary lines are shown consisting of these elements:

``````               a    b          c
GiB Mem : 18.7/15.738   [ ... ]
GiB Swap:  0.0/7.999    [ ... ]
``````

Where: a) is the percentage used; b) is the total available; and c) > is one of two visual graphs of those representations.

In the case of physical memory, the percentage represents the total minus the estimated avail noted above. The `Mem' graph itself is divided between the non-cached portion of used and any remaining memory not otherwise accounted for by avail. See topic 4b. SUMMARY AREA Commands and the `m' command for additional information on that special 4-way toggle.

# Source code of `top`

As of now, it can be verified by investigating the source code.

## Data passed to the graph view

``````#ifdef MEMGRAPH_OLD
my_misc = my_qued;
#else
my_misc = MEM_VAL(mem_TOT) - MEM_VAL(mem_AVL) - my_used;
#endif
Graph_mems->total = MEM_VAL(mem_TOT);
Graph_mems->part1 = my_used;
Graph_mems->part2 = my_misc;
``````

## Calculation in the graph view

``````   if (these->total > 0)
scale = 100.0 / these->total;
rx.pcnt_one = scale * these->part1;
rx.pcnt_two = scale * these->part2;
if (rx.pcnt_one + rx.pcnt_two > 100.0 || rx.pcnt_two < 0)
rx.pcnt_two = 0;
rx.pcnt_tot = rx.pcnt_one + rx.pcnt_two;
``````

## Data passed to the default view

``````      prT(bfT(0), mkM(MEM_VAL(mem_TOT))); prT(bfT(1), mkM(MEM_VAL(mem_FRE)));
prT(bfT(2), mkM(MEM_VAL(mem_USE))); prT(bfT(3), mkM(my_qued));
prT(bfT(4), mkM(MEM_VAL(swp_TOT))); prT(bfT(5), mkM(MEM_VAL(swp_FRE)));
prT(bfT(6), mkM(MEM_VAL(swp_USE))); prT(bfT(7), mkM(MEM_VAL(mem_AVL)));

snprintf(row, sizeof(row), N_unq(MEMORY_line1_fmt)
, scT(label), N_txt(WORD_abv_mem_txt), bfT(0), bfT(1), bfT(2), bfT(3));
Msg_row += sum_see(row, mem2UP);
``````

# On the reported inconsistency

• Did you check if your snapshots that you're matching are produced at the same system state? If printed at the same time, the used memory might be just 88.7% even in the default view.
• What is the version of your `top`? The current behavior of memory window has been introduced in 3.3.10.
• Which platform are you running it on? It seems there are some flags that can change the data passed to graph.

Corrected after further information and reveiw.

• (1) I'm pretty sure both data were captured at the same time (2) my `top` version is `procps-ng version 3.3.10` (3) the platform is `CentOS Linux release 7.6.1810 (Core) `
– jin
Dec 20, 2023 at 11:18