cprocess

Why is the top command output of memory different from the informations in the meminfo file?


So i am currently working on my own implementation of the top command using the ncurses and the Ubuntu proc folder system files and I am trying to display the memory informations on the fourth and fifith line of the top output.I have found the meminfo file in the /proc folder that contains the informations i am looking for.

However I have noticed that the informations in the file is slightly different from the one the top command show.I would like to understand if the meminfo file isn't the one i should be working with.


Solution

  • TL;DR Looks like top is getting the info from /proc/meminfo in ubuntu so items there should match with top (given a slight time offset)

    ================

    It looks like the top command comes from the procps package. I'm not sure if I have the source code of the most current (or even correct) top, but here's what I used: https://github.com/soarpenguin/procps-3.0.5/tree/e17c6e5fbedb7e8ff423586937aac42300ef11a6

    Looking at the code, it appears that the top code uses the meminfo() function found in sysinfo.c.

    Here's the code from top.c that seems to be building the memory lines...(from top.c)

    static void frame_storage (void)
    {
       meminfo();
       if (CHKw(Curwin, View_MEMORY)) {
          show_special(fmtmk(MEMORY_line1
             , kb_main_total, kb_main_used, kb_main_free, kb_main_buffers));
          show_special(fmtmk(MEMORY_line2
             , kb_swap_total, kb_swap_used, kb_swap_free, kb_main_cached));
          Msg_row += 2;
       }
    }
    

    Here's the code from sysinfo.c (in the same package but the /proc sub-dir) that is used to carry the info:

    #define MEMINFO_FILE "/proc/meminfo"
    

    ... defining where it gets the info. And the follow can be found starting at line 286 of sysinfo.c. There's the mem_table_struct and the associated strings that its using to fill the structure from /proc/meminfo:

    void meminfo(void){
      char namebuf[16]; /* big enough to hold any row name */
      mem_table_struct findme = { namebuf, NULL};
      mem_table_struct *found;
      char *head;
      char *tail;
      static const mem_table_struct mem_table[] = {
      {"Active",       &kb_active},
      {"Buffers",      &kb_main_buffers},
      {"Cached",       &kb_main_cached},
      {"Committed_AS", &kb_committed_as},
      {"Dirty",        &kb_dirty},
      {"HighFree",     &kb_high_free},
      {"HighTotal",    &kb_high_total},
      {"Inact_clean",  &kb_inact_clean},
      {"Inact_dirty",  &kb_inact_dirty},
      {"Inact_target", &kb_inact_target},
      {"Inactive",     &kb_inactive},
      {"LowFree",      &kb_low_free},
      {"LowTotal",     &kb_low_total},
      {"Mapped",       &kb_mapped},
      {"MemFree",      &kb_main_free},
      {"MemShared",    &kb_main_shared},
      {"MemTotal",     &kb_main_total},
      {"PageTables",   &kb_pagetables},
      {"ReverseMaps",  &nr_reversemaps},
      {"Slab",         &kb_slab},
      {"SwapCached",   &kb_swap_cached},
      {"SwapFree",     &kb_swap_free},
      {"SwapTotal",    &kb_swap_total},
      {"Writeback",    &kb_writeback}
      };
    

    So, yeah, /proc/meminfo carries the memory at a given time. Top.c uses it to display. Perhaps you're not using the right field or there's a time diffential but the code seems to be using /proc/meminfo.