Memoria total utilizada por el proceso Python?


¿Hay alguna manera de que un programa Python determine cuánta memoria está utilizando actualmente? He visto discusiones sobre el uso de memoria para un solo objeto, pero lo que necesito es el uso total de memoria para el proceso, para que pueda determinar cuándo es necesario comenzar a descartar datos almacenados en caché.

Author: jmlane, 2009-06-02

10 answers

Aquí es una solución útil que funciona para varios sistemas operativos, incluidos Linux, Windows 7, etc.:

import os
import psutil
process = psutil.Process(os.getpid())
print(process.memory_info().rss)

En mi instalación actual de Python 2.7, la última línea debería ser

print(process.get_memory_info()[0])

En su lugar (hubo un cambio en la API).

 182
Author: Basj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-21 14:16:15

Para Unixes (Linux, Mac OS X, Solaris) también puede usar la función getrusage() del módulo de biblioteca estándar resource. El objeto resultante tiene el atributo ru_maxrss, que da pico uso de memoria para el proceso de llamada:

>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
2656 # peak memory usage (bytes on OS X, kilobytes on Linux)

Los documentos de Python no tienen claro cuáles son exactamente las unidades, pero la página man de Mac OS X para getrusage(2) describe las unidades como bytes. La página man de Linux no está clara, pero parece ser equivalente a la información de /proc/self/status, que está en kilobytes .

La función getrusage() también se puede dar resource.RUSAGE_CHILDREN para obtener el uso para procesos hijos, y (en algunos sistemas) resource.RUSAGE_BOTH para el uso total (propio e hijo) del proceso.

resource es un módulo de biblioteca estándar.

Si solo te importa Linux, puedes simplemente revisar el archivo /proc/self/status como se describe en una pregunta similar.

 157
Author: Nathan Craike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39

En Windows, puede usar la página de inicio de WMI (, tienda de queso):


def memory():
    import os
    from wmi import WMI
    w = WMI('.')
    result = w.query("SELECT WorkingSet FROM Win32_PerfRawData_PerfProc_Process WHERE IDProcess=%d" % os.getpid())
    return int(result[0].WorkingSet)

En Linux (de python cookbook http://code.activestate.com/recipes/286222/:

import os
_proc_status = '/proc/%d/status' % os.getpid()

_scale = {'kB': 1024.0, 'mB': 1024.0*1024.0,
          'KB': 1024.0, 'MB': 1024.0*1024.0}

def _VmB(VmKey):
    '''Private.
    '''
    global _proc_status, _scale
     # get pseudo file  /proc/<pid>/status
    try:
        t = open(_proc_status)
        v = t.read()
        t.close()
    except:
        return 0.0  # non-Linux?
     # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
    i = v.index(VmKey)
    v = v[i:].split(None, 3)  # whitespace
    if len(v) < 3:
        return 0.0  # invalid format?
     # convert Vm value to bytes
    return float(v[1]) * _scale[v[2]]


def memory(since=0.0):
    '''Return memory usage in bytes.
    '''
    return _VmB('VmSize:') - since


def resident(since=0.0):
    '''Return resident memory usage in bytes.
    '''
    return _VmB('VmRSS:') - since


def stacksize(since=0.0):
    '''Return stack size in bytes.
    '''
    return _VmB('VmStk:') - since
 61
Author: codeape,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-17 16:19:45

En unix, puede usar la herramienta ps para monitorearlo:

$ ps u -p 1347 | awk '{sum=sum+$6}; END {print sum/1024}'

Donde 1347 es algún id de proceso. Además, el resultado está en MB.

 27
Author: bayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-02 09:59:10

Heapy (y amigos) puede ser lo que estás buscando.

Además, las cachés normalmente tienen un límite superior fijo en su tamaño para resolver el tipo de problema del que estás hablando. Por ejemplo, echa un vistazo a este decorador de caché LRU .

 7
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-02 09:55:47

Me gusta , gracias por @bayer. Ahora tengo una herramienta específica de conteo de procesos.

# Megabyte.
$ ps aux | grep python | awk '{sum=sum+$6}; END {print sum/1024 " MB"}'
87.9492 MB

# Byte.
$ ps aux | grep python | awk '{sum=sum+$6}; END {print sum " KB"}'
90064 KB

Adjuntar mi lista de procesos.

$ ps aux  | grep python
root       943  0.0  0.1  53252  9524 ?        Ss   Aug19  52:01 /usr/bin/python /usr/local/bin/beaver -c /etc/beaver/beaver.conf -l /var/log/beaver.log -P /var/run/beaver.pid
root       950  0.6  0.4 299680 34220 ?        Sl   Aug19 568:52 /usr/bin/python /usr/local/bin/beaver -c /etc/beaver/beaver.conf -l /var/log/beaver.log -P /var/run/beaver.pid
root      3803  0.2  0.4 315692 36576 ?        S    12:43   0:54 /usr/bin/python /usr/local/bin/beaver -c /etc/beaver/beaver.conf -l /var/log/beaver.log -P /var/run/beaver.pid
jonny    23325  0.0  0.1  47460  9076 pts/0    S+   17:40   0:00 python
jonny    24651  0.0  0.0  13076   924 pts/4    S+   18:06   0:00 grep python

Referencia

 3
Author: Chu-Siang Lai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39
import os, win32api, win32con, win32process
han = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION|win32con.PROCESS_VM_READ, 0, os.getpid())
process_memory = int(win32process.GetProcessMemoryInfo(han)['WorkingSetSize'])
 2
Author: Pedro Reis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-08 18:48:13

Usando sh y os para entrar en la respuesta de python bayer.

float(sh.awk(sh.ps('u','-p',os.getpid()),'{sum=sum+$6}; END {print sum/1024}'))

La respuesta está en megabytes.

 1
Author: Newmu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-16 23:35:02

Uso actual de la memoria del proceso actual en Linux, para python 2 y 3 y pypy:

import os
def getCurrentMemoryUsage():
    ''' Memory usage in kB '''

    f = open('/proc/{}/status'.format(os.getpid()))
    memusage = int(f.read().split('VmRSS:')[1].split('\n')[0][:-3].strip())
    f.close()

    return memusage

Lo he probado en Linux 4.4 y 4.9, pero cualquier versión de Linux debería funcionar.

Buscando en man proc y buscando la información en el archivo /proc/$PID/status, menciona versiones mínimas para algunos campos (como Linux 2.6.10 para "VmPTE"), pero el campo "VmRSS" (que uso aquí) no tiene tal mención. Por lo tanto, supongo que ha estado allí desde una versión temprana.

 1
Author: Luc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 08:51:13

A continuación se muestra mi decorador de funciones que permite rastrear cuánta memoria consumió este proceso antes de la llamada a la función, cuánta memoria usa después de la llamada a la función y cuánto tiempo se ejecuta la función.

import time
import os
import psutil


def elapsed_since(start):
    return time.strftime("%H:%M:%S", time.gmtime(time.time() - start))


def get_process_memory():
    process = psutil.Process(os.getpid())
    return process.get_memory_info().rss


def track(func):
    def wrapper(*args, **kwargs):
        mem_before = get_process_memory()
        start = time.time()
        result = func(*args, **kwargs)
        elapsed_time = elapsed_since(start)
        mem_after = get_process_memory()
        print("{}: memory before: {:,}, after: {:,}, consumed: {:,}; exec time: {}".format(
            func.__name__,
            mem_before, mem_after, mem_after - mem_before,
            elapsed_time))
        return result
    return wrapper

Entonces, cuando tienes alguna función decorada con ella

from utils import track

@track
def list_create(n):
    print("inside list create")
    x = [1] * n
    return x

Usted será capaz de ver esta salida:

inside list create
list_create: memory before: 45,928,448, after: 46,211,072, consumed: 282,624; exec time: 00:00:00
 1
Author: Ihor B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 08:50:43