real - La memoria total utilizada por el proceso de Python?
python blog (10)
¿Hay alguna manera de que un programa Python determine cuánta memoria está usando actualmente? He visto discusiones sobre el uso de la memoria para un solo objeto, pero lo que necesito es el uso total de la memoria para el proceso, de modo que pueda determinar cuándo es necesario comenzar a descartar los datos en caché.
Debajo está 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
Podrás 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
En Unix, puede usar la herramienta ps
para monitorearlo:
$ ps u -p 1347 | awk ''{sum=sum+$6}; END {print sum/1024}''
donde 1347 es alguna identificación de proceso. Además, el resultado está en MB.
En Windows, puede usar WMI ( página de inicio , 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)
En Linux (del libro de cocina Python 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
Me gusta, gracias por @bayer. Obtengo una herramienta de recuento de procesos específica, ahora.
# 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
Adjunte 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
Para Unixes (Linux, Mac OS X, Solaris) también puede usar la función getrusage()
del resource
módulo de biblioteca estándar. El objeto resultante tiene el atributo ru_maxrss
, que proporciona el uso máximo 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 son claros en cuanto a qué unidades son exactamente, 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 puede recibir resource.RUSAGE_CHILDREN
para obtener el uso de procesos secundarios y (en algunos sistemas) resource.RUSAGE_BOTH
para el uso total (propio y secundario) del proceso.
resource
es un módulo de biblioteca estándar.
Si solo le preocupa Linux, puede verificar el archivo /proc/self/status
como se describe en una pregunta similar .
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.
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 probé en Linux 4.4 y 4.9, pero cualquier versión de Linux debería funcionar.
Buscando en el programa man proc
y buscando la información en el archivo /proc/$PID/status
, menciona las 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 anterior.
Here hay una solución útil que funciona para varios sistemas operativos, incluidos Linux, Windows 7 x64:
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 debe ser
print(process.get_memory_info()[0])
en su lugar (hubo un cambio en la API).
Heapy (y amigos) pueden ser lo que estás buscando.
Además, los cachés generalmente 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 .
han = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION|win32con.PROCESS_VM_READ, 0, os.getpid())
process_memory = int(win32process.GetProcessMemoryInfo(han)[''WorkingSetSize''])