it-swarm.com.de

Gesamter Speicher, der von Python process?

Gibt es eine Möglichkeit für ein Python= Programm, um zu bestimmen, wie viel Speicher derzeit verwendet wird? Ich habe Diskussionen über die Speichernutzung für ein einzelnes Objekt gesehen, aber ich benötige die gesamte Speichernutzung für den Prozess , damit ich feststellen kann, wann zwischengespeicherte Daten gelöscht werden müssen.

208
rwallace

Hier ist eine nützliche Lösung für verschiedene Betriebssysteme, einschließlich Linux, Windows 7, etc .:

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

Auf meiner aktuellen Python 2.7-Installation mit psutil 5.6.3 sollte die letzte Zeile stehen

print(process.memory_info()[0])

stattdessen (es gab eine Änderung in der API).

Hinweis: do pip install psutil wenn es noch nicht installiert ist.

243
Basj

Für Unix-basierte Systeme (Linux, Mac OS X, Solaris) können Sie die Funktion getrusage() aus dem Standardbibliotheksmodul resource verwenden. Das resultierende Objekt hat das Attribut ru_maxrss, Das die maximale Speicherauslastung für den aufrufenden Prozess angibt:

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

Die Python-Dokumente notieren sich die Einheiten nicht. Beziehen Sie sich auf die Seite man getrusage.2 Ihres spezifischen Systems, um die Einheit auf den Wert zu überprüfen. Unter Ubuntu 18.04 wird die Einheit als Kilobyte angegeben. Unter Mac OS X sind es Bytes.

Die getrusage() -Funktion kann auch mit resource.RUSAGE_CHILDREN Angegeben werden, um die Verwendung für untergeordnete Prozesse abzurufen, und (auf einigen Systemen) mit resource.RUSAGE_BOTH Für die gesamte Prozessnutzung (für sich selbst und untergeordnete).

Wenn Sie sich nur für Linux interessieren, können Sie alternativ die Datei /proc/self/status Oder /proc/self/statm Lesen, wie in den anderen Antworten zu dieser Frage und this auch beschrieben.

181
Nathan Craike

Unter Windows können Sie WMI verwenden ( Homepage , 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)

Unter Linux (von 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
63
codeape

Unter Unix können Sie das Tool ps verwenden, um es zu überwachen:

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

dabei ist 1347 eine Prozess-ID. Das Ergebnis ist auch in MB.

29
bayer

Ich mag es , danke für @bayer. Ich bekomme jetzt ein bestimmtes Prozesszählwerkzeug.

# 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

Hänge meine Prozessliste an.

$ 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

Referenz

4
Chu-Siang Lai
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'])
3
Pedro Reis

Noch einfacher zu bedienen als /proc/self/status: /proc/self/statm. Es ist nur eine durch Leerzeichen getrennte Liste von mehreren Statistiken . Ich konnte nicht feststellen, ob beide Dateien immer vorhanden sind.

/ proc/[pid]/statm

Bietet Informationen zur Speichernutzung, gemessen in Seiten. Die Spalten sind:

  • größe (1) Gesamtprogrammgröße (wie VmSize in/proc/[pid]/status)
  • resident (2) resident set size (wie VmRSS in/proc/[pid]/status)
  • shared (3) Anzahl der freigegebenen residenten Seiten (d. h. durch eine Datei gesichert) (wie RssFile + RssShmem in/proc/[pid]/status)
  • text (4) text (code)
  • lib (5) Bibliothek (unbenutzt seit Linux 2.6; immer 0)
  • daten (6) Daten + Stapel
  • dt (7) Dirty Pages (unbenutzt seit Linux 2.6; immer 0)

Hier ist ein einfaches Beispiel:

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)

Das ergibt eine Liste, die ungefähr so ​​aussieht:

0
0
368640
368640
368640
638976
638976
909312
909312
909312

Sie können sehen, dass es nach ungefähr 3 Zuweisungen von 100.000 Bytes um ungefähr 300.000 Bytes springt.

3
Don Kirkby

Aktuelle Speichernutzung des aktuellen Prozesses unter Linux für Python 2, Python 3 und pypy, ohne Importe:

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())

Getestet unter Linux 4.4 und 4.9, aber auch eine frühe Linux-Version sollte funktionieren.

Hereinschauen man proc und suche nach den Infos auf dem /proc/$PID/status -Datei erwähnt Mindestversionen für einige Felder (wie Linux 2.6.10 für "VmPTE"), aber das Feld "VmRSS" (das ich hier verwende) wird nicht erwähnt. Daher gehe ich davon aus, dass es seit einer frühen Version dort drin ist.

3
Luc

Für Python 3.6 und psutil 5.4.5 ist es einfacher, die aufgelistete memory_percent() -Funktion zu verwenden hier .

import os
import psutil
process = psutil.Process(os.getpid())
print(process.memory_percent())
3
A.Ametov

Im Folgenden sehen Sie meinen Funktionsdekorator, mit dem Sie nachverfolgen können, wie viel Speicher dieser Prozess vor dem Funktionsaufruf verbraucht hat, wie viel Speicher er nach dem Funktionsaufruf belegt und wie lange die Funktion ausgeführt wird.

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

Also, wenn Sie eine Funktion haben, die damit dekoriert ist

from utils import track

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

Sie können diese Ausgabe sehen:

inside list create
list_create: memory before: 45,928,448, after: 46,211,072, consumed: 282,624; exec time: 00:00:00
2
Ihor B.

Verwenden Sie sh und os, um in die Antwort von python bayer zu gelangen.

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

Die Antwort ist in Megabyte.

1
Newmu

Bei Unix-Systemen gibt der Befehl time (/ usr/bin/time) diese Informationen aus, wenn Sie -v übergeben. Sehen Maximum resident set size unten, das ist das Maximum (Peak) Real (nicht virtuell) Speicher, der während der Programmausführung verwendet wurde:

$ /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
1