ssleert / nitch

nitch - incredibly fast system fetch written in nim
MIT License
519 stars 52 forks source link

Used Memory #35

Open DrunkenAlcoholic opened 1 year ago

DrunkenAlcoholic commented 1 year ago

Hi, Just want to say you have an excellent job on nitch, But as you probably already know, there are different versions on how used memory should be displayed, I did notice on nitch that it takes TotalMem - AvailableMem to get UsedMem. I just wanted to make you aware of the formula that htop uses and which has derived from a write up on Kernel.org https://www.kernel.org/doc/Documentation/filesystems/proc.txt

basically htop originally used MemUsed = MemTotal - MemFree - Cached - Buffers - SReclaimable + Shmem

Then some patches made it in the kernel changed the way SharedMem and Cached are calculated, I haven't personally read the patch notes https://lore.kernel.org/lkml/1455827801-13082-1-git-send-email-hannes@cmpxchg.org/ but it basically comes down to Shmem being part of cache so the accepted formula and the one htop uses is MemUsed = MemTotal - MemFree - Cached - Buffers - SReclaimable

I have implemented this is my fetch program written Pascal

// Get Memory and usage
function GetRamUsage(): string;
var
  strTmp, strMemTotal, strMemFree, strShmem, strBuffers, strCached,
  strSRclaimable: string;
  intMemUsage, intTotalMem: single;
  slMemInfo: TStringList;
begin
  Result := 'Error';
  // Set the name of the file that will be read
  slMemInfo := TStringList.Create;
  try
    slMemInfo.LoadFromFile('/proc/meminfo');
    try
      // Process MemTotal
      strTmp := slMemInfo.Strings[0];
      strMemTotal := Trim(ExtractString(strTmp, 'MemTotal:', 'kB'));

      // Process MemFree
      strTmp := slMemInfo.Strings[1];
      strMemFree := Trim(ExtractString(strTmp, 'MemFree:', 'kB'));

      // Process Buffers
      strTmp := slMemInfo.Strings[3];
      strBuffers := Trim(ExtractString(strTmp, 'Buffers:', 'kB'));

      // Process Cached
      strTmp := slMemInfo.Strings[4];
      strCached := Trim(ExtractString(strTmp, 'Cached:', 'kB'));

      // Process Shmem
      strTmp := slMemInfo.Strings[20];
      strShmem := Trim(ExtractString(strTmp, 'Shmem:', 'kB'));

      // Process SReclaimable
      strTmp := slMemInfo.Strings[25];
      strSRclaimable := Trim(ExtractString(strTmp, 'SReclaimable:', 'kB'));

      // Calc Mem Total
      intTotalMem := StrToFloat(strMemTotal);

      // Calc Mem Usage
      intMemUsage := (intTotalMem - StrToFloat(strMemFree) - StrToFloat(strBuffers) - 
        StrToFloat(strCached) - StrToFloat(strSRclaimable));
    finally
      slMemInfo.Free;
    end;

  except
    on E: EInOutError do
      writeln('File handling error occurred. Details: ', E.Message);
  end;

  Result := Format('%.2fGB / %.2fGB', [intMemUsage / (1024 * 1024), intTotalMem / (1024 * 1024)]);
end;

I am not saying you should change your formula, just making you aware of the accepted formula used at htop, everyone seems to have a different opinion on this particular topic, and it goes into a lot more discussion at kernel.org and htop github, hope this helps, if not disregard and deleted the topic.

fyi, programs like btop uses the same formula as nitch, but they are aware of htop and the kernel.org discription https://github.com/aristocratos/btop/issues/161