24 Stimmen

Python-Entsprechung von PHPs memory_get_usage()?

Ich habe bereits die folgende Frage gefunden aber ich habe mich gefragt, ob es einen schnelleren und schmutzigeren Weg gibt, eine Schätzung zu erhalten, wie viel Speicher der Python-Interpreter derzeit für mein Skript verwendet, das nicht auf externe Bibliotheken angewiesen ist.

Ich komme von PHP und benutzte memory_get_usage() y memory_get_peak_usage() für diesen Zweck und ich hoffte, ein Äquivalent zu finden.

31voto

Martin Geisler Punkte 71257

Eine einfache Lösung für Linux und andere Systeme mit /proc/self/status ist der folgende Code, den ich in einem Projekt von mir verwende:

def memory_usage():
    """Memory usage of the current process in kilobytes."""
    status = None
    result = {'peak': 0, 'rss': 0}
    try:
        # This will only work on systems with a /proc file system
        # (like Linux).
        status = open('/proc/self/status')
        for line in status:
            parts = line.split()
            key = parts[0][2:-1].lower()
            if key in result:
                result[key] = int(parts[1])
    finally:
        if status is not None:
            status.close()
    return result

Sie gibt die aktuelle und die maximale Größe des residenten Speichers zurück (das ist wahrscheinlich das, was die Leute meinen, wenn sie darüber sprechen, wie viel RAM eine Anwendung verwendet). Es ist einfach, sie zu erweitern, um andere Informationen aus der /proc/self/status Datei.

Für Neugierige: die vollständige Ausgabe von cat /proc/self/status sieht so aus:

% cat /proc/self/status
Name:   cat
State:  R (running)
Tgid:   4145
Pid:    4145
PPid:   4103
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 32
Groups: 20 24 25 29 40 44 46 100 1000 
VmPeak:     3580 kB
VmSize:     3580 kB
VmLck:         0 kB
VmHWM:       472 kB
VmRSS:       472 kB
VmData:      160 kB
VmStk:        84 kB
VmExe:        44 kB
VmLib:      1496 kB
VmPTE:        16 kB
Threads:        1
SigQ:   0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   03
Cpus_allowed_list:      0-1
Mems_allowed:   1
Mems_allowed_list:      0
voluntary_ctxt_switches:        0
nonvoluntary_ctxt_switches:     0

18voto

Nathan Craike Punkte 4595

Sie können auch die getrusage() Funktion aus dem Modul der Standardbibliothek resource . Das resultierende Objekt hat das Attribut ru_maxrss die den gesamten Spitzenspeicherverbrauch des aufrufenden Prozesses angibt:

>>> import resource
>>> resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
2656

En Python-Dokumente sind nicht klar, was die Einheiten genau sind, aber die Mac OS X-Manualseite für getrusage(2) beschreibt die Einheiten als Kilobytes.

Die Linux-Manpage ist nicht ganz klar, aber es scheint gleichwertig zu sein mit dem /proc/self/status Informationen (d.h. Kilobytes), die in der akzeptierten Antwort beschrieben sind. Für den gleichen Prozess wie oben, der unter Linux läuft, ergibt die in der akzeptierten Antwort aufgeführte Funktion:

>>> memory_usage()                                    
{'peak': 6392, 'rss': 2656}

Dies ist vielleicht nicht ganz so einfach zu bedienen wie die /proc/self/status Lösung, aber es handelt sich um eine Standardbibliothek, so dass sie (vorausgesetzt, die Einheiten sind standardisiert) plattformübergreifend und auch auf Systemen verwendbar sein sollte, die keine /proc/ (z. B. Mac OS X und andere Unixe, vielleicht Windows).

Auch, getrusage() Funktion kann auch gegeben werden resource.RUSAGE_CHILDREN um die Verwendung für Kindprozesse zu erhalten, und (auf einigen Systemen) resource.RUSAGE_BOTH für die gesamte (eigene und untergeordnete) Prozessnutzung.

Dies wird die memory_get_usage() Fall, beinhaltet aber nicht den Spitzenverbrauch. Ich bin mir nicht sicher, ob andere Funktionen des resource Modul kann einen Spitzenverbrauch ergeben.

11voto

johndodo Punkte 15249

Akzeptierte Antwortregeln, aber es könnte einfacher (und leichter übertragbar) sein, Folgendes zu verwenden psutil . Es tut das Gleiche und noch viel mehr.

UPDATE: muppy ist ebenfalls sehr praktisch (und viel besser dokumentiert als guppy/heapy).

2voto

dfa Punkte 110809

Versuchen Sie haufenweise

1voto

saaj Punkte 19920

/proc/self/status hat die folgenden relevanten Schlüssel:

  • VmPeak : Maximale Größe des virtuellen Speichers.
  • VmSize : Größe des virtuellen Speichers.
  • VmHWM : Spitzenwert der Einwohnerzahl ("Hochwassermarke").
  • VmRSS : Größe des Residenten-Sets.

Wenn es sich also um residenten Speicher handelt, kann der folgende Code verwendet werden, um ihn abzurufen:

def get_proc_status(keys = None):
    with open('/proc/self/status') as f:
        data = dict(map(str.strip, line.split(':', 1)) for line in f)

    return tuple(data[k] for k in keys) if keys else data

peak, current = get_proc_status(('VmHWM', 'VmRSS'))
print(peak, current)  # outputs: 14280 kB 13696 kB

Hier ist ein Artikel von speicher_profiler Der Autor das erklärt, dass getrusage 's ru_maxrss ist nicht immer eine praktische Maßnahme. Beachten Sie auch das, VmHWM kann abweichen von ru_maxrss (was ich in einigen Fällen sehe ru_maxrss größer ist). Im einfachen Fall sind sie jedoch identisch:

import resource

def report():
    maxrss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    peak, current = get_proc_status(('VmHWM', 'VmRSS'))
    print(current, peak, maxrss)

report()

s = ' ' * 2 ** 28  # 256MiB
report()

s = None
report()

Außerdem gibt es hier eine sehr verständliche und informative Fallstudie von auf Autoren die erklärt, was Kernel-, virtueller und residenter Speicher sind und wie sie voneinander abhängen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X