Mémoire totale utilisée par le processus Python?

y a-t-il un moyen pour un programme Python de déterminer combien de mémoire il utilise actuellement? J'ai vu des discussions sur l'utilisation de la mémoire pour un seul objet, mais ce dont j'ai besoin est l'utilisation totale de la mémoire pour le processus, afin que je puisse déterminer quand il est nécessaire de commencer à rejeter des données cachées.

160
demandé sur jmlane 2009-06-02 13:50:40

10 réponses

Ici est une solution très pratique qui fonctionne pour différents systèmes d'exploitation, y compris Linux, Windows 7, etc.:

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

sur mon installation actuelle de Python 2.7, la dernière ligne doit être

print(process.get_memory_info()[0])

à la place (il y a eu un changement dans L'API).

182
répondu Basj 2018-05-21 14:16:15

pour Unixes (Linux, Mac OS X, Solaris) vous pouvez également utiliser la fonction getrusage() du module de bibliothèque standard resource . L'objet résultant a l'attribut ru_maxrss , qui donne peak utilisation de la mémoire pour le processus d'appel:

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

les Python docs ne sont pas clairs sur ce que sont exactement les unités, mais le Mac OS X man page pour getrusage(2) décrit les unités comme octets . La page de manuel de Linux n'est pas claire, mais elle semble être équivalente à l'information de /proc/self/status , qui est dans kilooctets .

la fonction getrusage() peut aussi être donnée resource.RUSAGE_CHILDREN pour obtenir l'utilisation pour les processus enfants, et (sur certains systèmes) resource.RUSAGE_BOTH pour l'utilisation totale (Auto et enfant) des processus.

resource est un module de bibliothèque standard.

si vous ne vous souciez que de Linux, vous pouvez simplement consulter le fichier /proc/self/status comme décrit dans une question similaire .

157
répondu Nathan Craike 2017-05-23 12:34:39

Sur Windows, vous pouvez utiliser WMI ( page d'accueil , cheeseshop ):


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)

Sur Linux (à partir 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
répondu codeape 2016-03-17 16:19:45

sur unix, vous pouvez utiliser l'outil ps pour le surveiller:

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

où 1347 est un numéro d'identification de processus. Aussi, le résultat est en MO.

27
répondu bayer 2009-06-02 09:59:10

Heapy (et ses amis) peut être ce que vous cherchez.

en outre, les caches ont généralement une limite supérieure fixe sur leur taille pour résoudre le genre de problème dont vous parlez. Par exemple, regardez ce décorateur de cache LRU .

7
répondu Hank Gay 2009-06-02 09:55:47

j'aime il , je vous remercie pour @bayer. J'ai un outil spécifique de comptage de processus, maintenant.

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

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

joindre ma liste de processus.

$ 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

référence

3
répondu Chu-Siang Lai 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
répondu Pedro Reis 2018-06-08 18:48:13

utilise sh and os pour entrer dans la réponse de python bayer.

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

la réponse est en mégaoctets.

1
répondu Newmu 2013-05-16 23:35:02

utilisation Courante de la mémoire du processus en cours sur Linux, pour python 2 et 3 et 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

Je l'ai testé sur Linux 4.4 et 4.9, mais toute version Linux devrait fonctionner.

en regardant man proc et en cherchant les informations sur le fichier /proc/$PID/status , il mentionne des versions minimales pour certains champs (comme Linux 2.6.10 pour" VmPTE"), mais le champ" VmRSS " (que j'utilise ici) n'a pas une telle mention. Donc je suppose qu'il a été là depuis une version ancienne.

1
répondu Luc 2018-01-23 08:51:13

ci-dessous est mon décorateur de fonction qui permet de suivre combien de mémoire ce processus consommé avant l'appel de fonction, combien de mémoire il utilise après l'appel de fonction, et combien de temps la fonction est exécutée.

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

donc, quand vous avez quelque fonction décorée avec elle

from utils import track

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

vous pourrez voir cette sortie:

inside list create
list_create: memory before: 45,928,448, after: 46,211,072, consumed: 282,624; exec time: 00:00:00
1
répondu Ihor B. 2018-02-22 08:50:43