Überprüfen Sie den verfügbaren Speicher unter Linux


9

Ich schreibe ein Python-Skript, das 4K- Videos herunterlädt und auf Anfrage abspielt. Wenn mein Gerätespeicher 7,2 GB überschreitet, wird das Video mit der geringsten Anzahl von Ansichten gelöscht.

Mit dem Befehl free oder top kann ich die Speicherinformationen abrufen. Aber wie kann ich den gesamten Speicher nutzen ? Damit ich dies an die Python-Funktion zurückgeben kann, um es mit dem Speicherschwellenwert zu vergleichen.


2
Siehe auch stackoverflow.com/questions/276052/… für andere Möglichkeiten, dies in Python zu tun. Insbesondere wenn Sie Portabilität zwischen verschiedenen Betriebssystemen benötigen, psutilscheint das Python-Modul der richtige Weg zu sein.
Brian Minton

Antworten:


10

Prozentsatz des verwendeten Speichers (ohne Puffer und Cache):

free | awk 'FNR == 3 {print $3/($3+$4)*100}'

Für Ihre Frage haben Sie hinzugefügt: "über 7,2 Gigabyte", aber ich würde annehmen, dass ein Prozentsatz flexibler sein könnte.


Um dies zu erweitern, kann dasselbe für "prozentualen freien Speicher" verwendet werden:

free | awk 'FNR == 3 {print $4/($3+$4)*100}'

awkist ein Muster-Scan-Tool mit vielen Parametern. FNR ist die Nummer des Eingabedatensatzes in der aktuellen Eingabedatei. Grundsätzlich die aktuell verarbeitete Zeile. FNR sucht also nach der 3. Zeile, in der die Zahlen Ihren Wünschen entsprechen. Die $ 3 und $ 4 zeigen auf die 3. und 4. Spalte. Wenn Sie die Nummer selbst möchten, verwenden Sie:

free | awk 'FNR == 3 {print $3}'
free | awk 'FNR == 3 {print $4}'

Beispiel:

$ free
             total       used       free     shared    buffers     cached
Mem:      16419996   16144316     275680          0     447220   12589412
-/+ buffers/cache:    3107684   13312312
Swap:     16761852      38532   16723320
~$ free | awk 'FNR == 3 {print $3}'
3109056
~$ free | awk 'FNR == 3 {print $4}'
13311240

Wenn Sie mit Puffern und Cache wollen: FNR = 2. Wenn Sie tauschen möchten, ist FNR = 4.


19

Sie können auch die freeInformationsquelle lesen /proc/meminfo:

~ head /proc/meminfo
MemTotal:        4039168 kB
MemFree:         2567392 kB
MemAvailable:    3169436 kB
Buffers:           81756 kB
Cached:           712808 kB
SwapCached:            0 kB
Active:           835276 kB
Inactive:         457436 kB
Active(anon):     499080 kB
Inactive(anon):    17968 kB

In Python zum Beispiel:

with open('/proc/meminfo') as file:
    for line in file:
        if 'MemFree' in line:
            free_mem_in_kb = line.split()[1]
            break

Sie erhalten den freien Speicher in KB in der free_mem_in_kbVariablen. Mit etwas Ähnlichem für den Gesamtspeicher können Sie die Werte subtrahieren (oder Puffer addieren, zwischengespeichert usw.).

Sie können auch ein Wörterbuch der Werte in der Datei erstellen:

from collections import namedtuple
MemInfoEntry = namedtuple('MemInfoEntry', ['value', 'unit'])

meminfo = {}
with open('/proc/meminfo') as file:
    for line in file:
        key, value, *unit = line.strip().split()
        meminfo[key.rstrip(':')] = MemInfoEntry(value, unit)

Rufen Sie dann meminfo['MemAvailable'].valuezum Beispiel die Werte mit ab .


4
+1 - Die Verwendung von / proc / meminfo ist viel eleganter als der Versuch, die Ausgabe von "free" zu analysieren. Zugegeben, das Format der Ausgabe von free wird sich jetzt wahrscheinlich nicht ändern, aber ich hatte kürzlich eine schreckliche Skriptunterbrechung und machte einen Dienst funktionsunfähig, da es darauf ankam, die für Menschen lesbare Ausgabe eines anderen Befehls zu aktivieren, dessen Format sich aufgrund des Dienstprogramms geringfügig geändert hat aktualisiert werden.
Carcer

3
@Carcer "Zugegeben, das Format der Ausgabe von free wird sich jetzt wahrscheinlich nicht ändern ..." - Genau das ist vor ungefähr 4 Jahren passiert . Verlassen Sie sich nicht darauf, die Ausgabe solcher Tools zu analysieren, wenn Sie helfen können.
Marcelm

4
@carcer Warum ändert sich die Leistung von /proc/meminfolangfristig weniger wahrscheinlich als die von free? Die Wahl scheint zwischen dem Parsen des einen oder anderen zu liegen.
Federico Poloni

4
@FedericoPoloni, weil Linus Änderungen hasst, /proc/meminfodie den Benutzerraum beschädigen, und seit langer Zeit Benutzern ausgesetzt ist.
Muru

6
@FedericoPoloni Beachten Sie, dass dies /proc/meminfonicht für Menschen gedacht ist (die mit Änderungen in der Ausgabeformatierung umgehen können), sondern für andere Programme (die bei Änderungen möglicherweise nicht funktionieren ). Wie Muru Notes bemühen sich Linux-Kernel-Entwickler, den Benutzerraum nicht mithilfe dokumentierter APIs (von denen / proc / meminfo eine ist) zu unterbrechen . Darüber hinaus besteht das Format für /proc/meminfomehr oder weniger Schlüssel-Wert-Paare, sodass das Hinzufügen neuer Felder erfolgen kann, ohne die Abwärtskompatibilität zu beeinträchtigen. Brechende Änderungen könnten immer noch passieren, aber ich denke, sie sind weniger wahrscheinlich als für free.
Marcelm

2

Der Python-Code von muru hat mich fasziniert, ihn in einer Decorator-Klasse zu verwenden, um den Speicherverbrauch einer Funktion zu messen.

class memoryit:

    def FreeMemory():
        with open('/proc/meminfo') as file:
            for line in file:
                if 'MemFree' in line:
                    free_memKB = line.split()[1]
                    return (float(free_memKB)/(1024*1024))    # returns GBytes float

    def __init__(self, function):    # Decorator class to print the memory consumption of a 
        self.function = function     # function/method after calling it a number of iterations

    def __call__(self, *args, iterations = 1, **kwargs):
        before = memoryit.FreeMemory()
        for i in range (iterations):
            result = self.function(*args, **kwargs)
        after = memoryit.FreeMemory()
        print ('%r memory used: %2.3f GB' % (self.function.__name__, (before - after) / iterations))
        return result

Funktion zur Verbrauchsmessung:

@memoryit
def MakeMatrix (dim):
    matrix = []   
    for i in range (dim):
        matrix.append([j for j in range (dim)])
    return (matrix)

Verwendungszweck:

print ("Starting memory:", memoryit.FreeMemory()) 
m = MakeMatrix(10000)    
print ("Ending memory:", memoryit.FreeMemory() )

Ausdrucken:

Starting memory: 10.58599853515625
'MakeMatrix' memory used: 3.741 GB
Ending memory: 6.864116668701172
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.