0

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?

jin
  • 3

1 Answers1

0

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.

Related threads:

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.

j824h
  • 18
  • (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 '23 at 11:18