How to display memory used by processes in human readable form using Python script

Display memory used by processes in human readable form using Python script.

Install cross-platform psutil library for process and system monitoring in Python.

$ sudo apt-get install python-psutil
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  python-psutil-doc
The following NEW packages will be installed:
  python-psutil
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 127 kB of archives.
After this operation, 646 kB of additional disk space will be used.
Get:1 http://ftp.task.gda.pl/debian stretch/main amd64 python-psutil amd64 5.0.1-1 [127 kB]
Fetched 127 kB in 0s (476 kB/s)       
Selecting previously unselected package python-psutil.
(Reading database ... 125847 files and directories currently installed.)
Preparing to unpack .../python-psutil_5.0.1-1_amd64.deb ...
Unpacking python-psutil (5.0.1-1) ...
Setting up python-psutil (5.0.1-1) ...

Python script that will display top twenty processes using the most memory.

#!/usr/bin/python

import os
import psutil

import math

def pretty_memory_size(nbytes):
  metric = ("B", "kB", "MB", "GB", "TB")
  if nbytes == 0:
    return "%s %s" % ("0", "B")

  nunit = int(math.floor(math.log(nbytes, 1024)))
  nsize = round(nbytes/(math.pow(1024, nunit)), 2)
  return '%s %s' % (format(nsize, ".2f"), metric[nunit])

for p in sorted(psutil.process_iter(), key=lambda p: p.memory_info().rss, reverse=True)[:20]:
    print("%5s %10s %s" % (p.pid, pretty_memory_size(p.memory_info().rss), " ".join(filter(None,p.cmdline())) if p.cmdline() else p.name()))

Sample usage.

$ python process_mem.py
16933  577.25 MB unicorn worker[0] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru
25883  573.46 MB unicorn worker[1] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru
 4342  549.24 MB unicorn worker[2] -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru
 4185  515.62 MB sidekiq 5.2.1 gitlab-rails [0 of 25 busy]
 4228  449.37 MB unicorn master -D -E production -c /var/opt/gitlab/gitlab-rails/etc/unicorn.rb /opt/gitlab/embedded/service/gitlab-rails/config.ru
 4154  153.43 MB /opt/gitlab/embedded/bin/prometheus -web.listen-address=localhost:9090 -storage.local.path=/var/opt/gitlab/prometheus/data -storage.local.chunk-encoding-version=2 -storage.local.target-heap-size=191620055 -config.file=/var/opt/gitlab/prometheus/prometheus.yml
  396   81.21 MB /usr/bin/dockerd -H fd://
 4150   73.54 MB /opt/gitlab/embedded/bin/postgres -D /var/opt/gitlab/postgresql/data
 4019   66.63 MB ruby /opt/gitlab/embedded/service/gitaly-ruby/bin/gitaly-ruby 3999 /tmp/gitaly-ruby726085140/socket.1
 4016   65.13 MB ruby /opt/gitlab/embedded/service/gitaly-ruby/bin/gitaly-ruby 3999 /tmp/gitaly-ruby726085140/socket.0
 4011   41.59 MB /opt/gitlab/embedded/bin/ruby /opt/gitlab/embedded/bin/gitlab-mon web -c /var/opt/gitlab/gitlab-monitor/gitlab-monitor.yml
  434   38.57 MB docker-containerd --config /var/run/docker/containerd/containerd.toml
17094   35.31 MB postgres: gitlab gitlabhq_production [local] idle
 4353   35.30 MB postgres: gitlab gitlabhq_production [local] idle
 8948   35.25 MB postgres: gitlab gitlabhq_production [local] idle
24312   35.18 MB postgres: gitlab gitlabhq_production [local] idle
24306   35.02 MB postgres: gitlab gitlabhq_production [local] idle
24437   34.95 MB postgres: gitlab gitlabhq_production [local] idle
24321   34.83 MB postgres: gitlab gitlabhq_production [local] idle
24359   34.82 MB postgres: gitlab gitlabhq_production [local] idle