Existe-t-il un moyen pour un programme Python de déterminer la quantité de mémoire qu'il utilise actuellement? J'ai assisté à des discussions sur l'utilisation de la mémoire pour un seul objet, mais ce dont j'ai besoin, c'est de l'utilisation totale de la mémoire pour le processus, afin de pouvoir déterminer quand il est nécessaire de commencer à supprimer les données en cache.
Here est une solution utile qui fonctionne pour différents systèmes d'exploitation, notamment Linux, Windows 7, etc.:
import os
import psutil
process = psutil.Process(os.getpid())
print(process.memory_info().rss) # in bytes
Sur mon Python 2.7 actuel avec psutil 5.6.3, la dernière ligne doit être
print(process.memory_info()[0])
au lieu de cela (il y avait un changement dans l'API).
Remarque: faites pip install psutil
s'il n'est pas encore installé.
Pour les systèmes Unix (Linux, Mac OS X, Solaris), vous pouvez utiliser la fonction getrusage()
à partir du module de bibliothèque standard resource
. L'objet résultant a l'attribut ru_maxrss
, qui donne l'utilisation de la mémoire de pointe pour le processus appelant:
>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
2656 # peak memory usage (kilobytes on Linux, bytes on OS X)
Les documents Python ne notent pas les unités. Reportez-vous à la page man getrusage.2
de votre système pour vérifier la valeur de l'unité. Sur Ubuntu 18.04, l’unité est notée en kilo-octets. Sur Mac OS X, ce sont des octets.
La fonction getrusage()
peut également recevoir resource.RUSAGE_CHILDREN
pour obtenir l'utilisation des processus enfants et (sur certains systèmes) resource.RUSAGE_BOTH
pour l'utilisation totale des processus (auto et enfant).
Si vous ne vous souciez que de Linux, vous pouvez également lire le fichier /proc/self/status
ou /proc/self/statm
comme décrit dans les autres réponses à cette question et ceci un aussi.
Sous 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)
Sous 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
Sous unix, vous pouvez utiliser l'outil ps
pour le surveiller:
$ ps u -p 1347 | awk '{sum=sum+$6}; END {print sum/1024}'
où 1347 est un identifiant de processus. En outre, le résultat est en Mo.
J'aime it , merci pour @bayer. Je reçois un outil de comptage de processus spécifique, maintenant.
# 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
Joignez 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
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'])
Encore plus facile à utiliser que /proc/self/status
: /proc/self/statm
. C'est juste une liste délimitée par des espaces de plusieurs statistiques . Je n'ai pas été en mesure de dire si les deux fichiers sont toujours présents.
/ proc/[pid]/statm
Fournit des informations sur l'utilisation de la mémoire, mesurée en pages. Les colonnes sont:
- taille (1) taille totale du programme (identique à VmSize dans/proc/[pid]/status)
- resident (2) resident set size (identique à VmRSS dans/proc/[pid]/status)
- shared (3) nombre de pages partagées résidentes (c'est-à-dire, sauvegardées par un fichier) (identique à RssFile + RssShmem dans/proc/[pid]/status)
- text (4) text (code)
- bibliothèque lib (5) (inutilisée depuis Linux 2.6; toujours 0)
- data (6) data + stack
- dt (7) pages altérées (inutilisées depuis Linux 2.6; toujours 0)
Voici un exemple simple:
from pathlib import Path
from resource import getpagesize
PAGESIZE = getpagesize()
PATH = Path('/proc/self/statm')
def get_resident_set_size() -> int:
"""Return the current resident set size in bytes."""
# statm columns are: size resident shared text lib data dt
statm = PATH.read_text()
fields = statm.split()
return int(fields[1]) * PAGESIZE
data = []
start_memory = get_resident_set_size()
for _ in range(10):
data.append('X' * 100000)
print(get_resident_set_size() - start_memory)
Cela produit une liste qui ressemble à ceci:
0
0
368640
368640
368640
638976
638976
909312
909312
909312
Vous pouvez constater qu’il saute d’environ 300 000 octets après environ 3 attributions de 100 000 octets.
Utilisation actuelle de la mémoire du processus en cours sous Linux, pour Python 2, Python 3 et pypy, sans aucune importation:
def getCurrentMemoryUsage():
''' Memory usage in kB '''
with open('/proc/self/status') as f:
memusage = f.read().split('VmRSS:')[1].split('\n')[0][:-3]
return int(memusage.strip())
Testé sur Linux 4.4 et 4.9, mais même une version antérieure de Linux devrait fonctionner.
La recherche dans man proc
et la recherche d'informations sur le fichier /proc/$PID/status
mentionnent les versions minimales de certains champs (comme Linux 2.6.10 pour "VmPTE"), mais le champ "VmRSS" (que j'utilise). ici) n'a pas une telle mention. Par conséquent, je suppose que cela existe depuis la première version.
Pour Python 3.6 et psutil 5.4.5, il est plus facile d'utiliser la fonction memory_percent()
listée ici .
import os
import psutil
process = psutil.Process(os.getpid())
print(process.memory_percent())
Ci-dessous, mon décorateur de fonctions, qui permet de suivre la quantité de mémoire utilisée par ce processus avant l'appel de fonction, la quantité de mémoire utilisée par celui-ci après l'appel de fonction et la durée d'exécution de la fonction.
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.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 une fonction décorée avec elle
from utils import track
@track
def list_create(n):
print("inside list create")
return [1] * n
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
Utiliser sh et os pour entrer dans la réponse de python bayer.
float(sh.awk(sh.ps('u','-p',os.getpid()),'{sum=sum+$6}; END {print sum/1024}'))
La réponse est en mégaoctets.
Pour les systèmes Unix, la commande time
(/ usr/bin/time) vous donne ces informations si vous passez -v. Voir Maximum resident set size
ci-dessous, qui est le maximum (pic) réel (non virtuel) mémoire utilisée pendant l'exécution du programme:
$ /usr/bin/time -v ls /
Command being timed: "ls /"
User time (seconds): 0.00
System time (seconds): 0.01
Percent of CPU this job got: 250%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 315
Voluntary context switches: 2
Involuntary context switches: 0
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0