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.
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).
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 .
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
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.
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 .
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
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'])
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.
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.
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