llnnmc
12/15/2019 - 1:19 PM

procsmem.py

procsmem.py

#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
Show detailed memory usage about all (querable) processes.

Processes are sorted by their "USS" (Unique Set Size) memory, which is
probably the most representative metric for determining how much memory
is actually being used by a process.

This is similar to "smem" cmdline utility on Linux:
https://www.selenic.com/smem/

$ python procsmem.py
PID     User                 Cmdline                                                                              USS     PSS    Swap     RSS
============================================================================================================================================
5396    PC2018\\Administrator C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\bin\\pycharm64.exe                       1.2G                    1.3G
11296   PC2018\\Administrator C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdgeCP.exe   131.0M                  189.8M
10024   PC2018\\Administrator C:\\Program Files (x86)\\Tencent\\TIM\\Bin\\TIM.exe /hosthwnd=263624 /hostname=QQ_IPC   78.8M                  107.2M
11896   PC2018\\Administrator C:\\WINDOWS\\Explorer.EXE                                                            76.6M                  148.4M
5392    PC2018\\Administrator C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdgeCP.exe    71.8M                  132.3M
252     PC2018\\Administrator C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdge.exe -S   56.9M                  117.0M
15648   PC2018\\Administrator C:\\Program Files (x86)\\Microsoft Office\\Root\\Office16\\ONENOTE.EXE                  51.4M                   85.5M
4744    PC2018\\Administrator C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdgeCP.exe    46.1M                  105.2M
884     PC2018\\Administrator C:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe                                   38.7M                   69.2M
15064   PC2018\\Administrator C:\\Windows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdgeCP.exe    32.8M                   79.4M
"""

from __future__ import print_function
import sys
import psutil

if not (psutil.LINUX or psutil.MACOS or psutil.WINDOWS):
    sys.exit("platform not supported")

def convert_bytes(n):
    symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    prefix = {}
    for i, s in enumerate(symbols):
        prefix[s] = 1 << (i + 1) * 10
    for s in reversed(symbols):
        if n >= prefix[s]:
            value = float(n) / prefix[s]
            return '%.1f%s' % (value, s)
    return "%sB" % n

def main():
    ad_pids = []
    procs = []
    for p in psutil.process_iter():
        with p.oneshot():
            try:
                mem = p.memory_full_info()
                info = p.as_dict(attrs=["cmdline", "username"])
            except psutil.AccessDenied:
                ad_pids.append(p.pid)
            except psutil.NoSuchProcess:
                pass
            else:
                p._uss = mem.uss
                p._rss = mem.rss
                if not p._uss:
                    continue
                p._pss = getattr(mem, "pss", "")
                p._swap = getattr(mem, "swap", "")
                p._info = info
                procs.append(p)

    procs.sort(key=lambda p: p._uss, reverse = True)
    templ = "%-7s %-20s %-80s %7s %7s %7s %7s"
    print(templ % ("PID", "User", "Cmdline", "USS", "PSS", "Swap", "RSS"))
    print("=" * 140)
    for p in procs[:10]:
        line = templ % (
            p.pid,
            p._info["username"][:20],
            " ".join(p._info["cmdline"])[:80],
            convert_bytes(p._uss),
            convert_bytes(p._pss) if p._pss != "" else "",
            convert_bytes(p._swap) if p._swap != "" else "",
            convert_bytes(p._rss),
        )
        print(line)
    if ad_pids:
        print("warning: access denied for %s pids" % (len(ad_pids)),
              file=sys.stderr)

if __name__ == '__main__':
    sys.exit(main())