Befehle sind zum Beispiel sed
Programme und Programme sind codierte Logik innerhalb einer Datei und diese Dateien befinden sich irgendwo auf der Festplatte. Wenn jedoch Befehle ausgeführt werden, wird eine Kopie ihrer Dateien von der Festplatte in den RAM gestellt , wo sie zum Leben erweckt werden und Dinge tun können und als Prozesse bezeichnet werden .
Prozesse können andere Dateien verwenden, darin lesen oder schreiben. In diesem Fall werden diese Dateien als offene Dateien bezeichnet. Es gibt einen Befehl , um alle geöffneten Dateien durch alle laufenden Prozesse zur Liste: lsof
.
OK, ich frage mich also, ob die doppelte Lebensdauer eines Befehls, einer auf der Festplatte, der andere im RAM, auch für andere Arten von Dateien gilt, zum Beispiel für Dateien, für die keine Logik programmiert ist, die aber einfach Container sind Daten.
Ich gehe davon aus, dass auch von Prozessen geöffnete Dateien in den Arbeitsspeicher geladen werden. Ich weiß nicht, ob es wahr ist, es ist nur eine Intuition.
Könnte jemand einen Sinn daraus machen?
Antworten:
Das ist (im Allgemeinen) falsch. Wenn ein Programm ausgeführt wird (durch Ausführen (2) ...), ändert der Prozess (der dieses Programm ausführt ) seinen virtuellen Adressraum und der Kernel konfiguriert die MMU für diesen Zweck neu. Lesen Sie auch über den virtuellen Speicher . Beachten Sie, dass Anwendungsprogramme ihren virtuellen Adressraum mithilfe von mmap (2) &
munmap
& mprotect (2) ändern können , das auch vom dynamischen Linker verwendet wird (siehe ld-linux (8) ). Siehe auch madvise (2) & posix_fadvise (2) & mlock (2) .Zukünftige Seitenfehler werden vom Kernel verarbeitet, um (träge) Seiten aus der ausführbaren Datei zu laden. Lesen Sie auch über das Verprügeln .
Der Kernel verwaltet einen großen Seiten-Cache . Lesen Sie auch über Copy-on-Write . Siehe auch readahead (2) .
Für Systemaufrufe wie read (2) & write (2) wird auch der Seiten-Cache verwendet. Wenn sich die zu lesenden Daten darin befinden, wird keine Platten-E / A-Operation durchgeführt. Wenn Festplatten-E / A benötigt wird, werden die gelesenen Daten sehr wahrscheinlich in den Seiten-Cache gestellt. Wenn Sie also in der Praxis denselben Befehl zweimal ausführen, kann es vorkommen, dass beim zweiten Mal keine physischen E / A-Vorgänge auf der Festplatte ausgeführt werden (wenn Sie eine alte rotierende Festplatte - keine SSD - haben, hören Sie dies möglicherweise. oder beobachten Sie sorgfältig Ihre Festplatten-LED).
Ich empfehle, ein Buch wie Betriebssysteme zu lesen : Drei einfache Teile (frei herunterladbar, eine PDF-Datei pro Kapitel), in denen dies alles erklärt wird.
Siehe auch Linux Ate My RAM und führen Befehle wie
xosview
,top
,htop
odercat /proc/self/maps
odercat /proc/$$/maps
(siehe proc (5) ).PS. Ich konzentriere mich auf Linux, aber andere Betriebssysteme haben auch virtuellen Speicher und Seiten-Cache.
quelle
Nein, eine Datei wird beim Öffnen nicht automatisch in den Speicher eingelesen. Das wäre schrecklich ineffizient.
sed
Liest beispielsweise wie viele andere Unix-Tools seine Eingabe zeilenweise. Es muss selten mehr als die aktuelle Zeile gespeichert werden.Mit ist
awk
es das selbe. Es wird jeweils ein Datensatz gelesen , der standardmäßig eine Zeile ist. Wenn Sie Teile der Eingabedaten in Variablen speichern, ist das natürlich zusätzlich 1 .Einige Leute haben die Angewohnheit, Dinge wie zu tun
Da die Schal der erweitern müssen
$(cat file)
Befehlssubstitutions vollständig , bevor noch die erste Iteration desfor
Laufschleife, dies wird die gesamte liestfile
in den Speicher (in den von der Shell benutzten Speicher der auszuführendefor
Schleife). Das ist ein bisschen albern und auch unelegant. Stattdessen sollte man tunDies wird
file
zeilenweise verarbeitet (aber lesen Sie "IFS = read -r line" ).Das zeilenweise Verarbeiten von Dateien in der Shell ist jedoch nur selten erforderlich, da die meisten Dienstprogramme ohnehin zeilenorientiert sind (siehe Warum wird eine Shell-Schleife zum Verarbeiten von Text verwendet, der als fehlerhaft angesehen wird? ).
Ich arbeite in der Bioinformatik und bei der Verarbeitung großer Mengen genomischer Daten wäre ich nicht in der Lage, viel zu tun, wenn ich nicht nur die Teile der Daten im Speicher belasse, die unbedingt erforderlich sind. Wenn ich beispielsweise die Datenbits entfernen muss, mit denen Personen aus einem 1-Terabyte-Datensatz mit DNA-Varianten in einer VCF-Datei identifiziert werden können (da diese Art von Daten nicht öffentlich zugänglich gemacht werden kann), gehe ich zeilenweise vor Bearbeitung mit einem einfachen
awk
Programm (dies ist möglich, da das VCF-Format zeilenorientiert ist). Ich nicht lesen Sie die Datei in den Speicher, verarbeiten es dort, und schreiben Sie es wieder heraus! Wenn die Datei komprimiert wäre, würde ich sie durchlaufen lassenzcat
odergzip -d -c
, dagzip
Streaming-Verarbeitung von Daten, auch nicht die gesamte Datei in den Speicher lesen.Selbst bei nicht zeilenorientierten Dateiformaten wie JSON oder XML gibt es Stream-Parser, mit denen große Dateien verarbeitet werden können, ohne dass alles im RAM gespeichert werden muss.
Bei ausführbaren Dateien ist dies etwas komplizierter, da gemeinsam genutzte Bibliotheken bei Bedarf geladen und / oder von Prozessen gemeinsam genutzt werden können (siehe z. B. Laden von gemeinsam genutzten Bibliotheken und RAM-Nutzung ).
Caching habe ich hier nicht erwähnt. Dies ist die Aktion, bei der RAM zum Speichern von Daten verwendet wird, auf die häufig zugegriffen wird. Kleinere Dateien (z. B. ausführbare Dateien) können vom Betriebssystem in der Hoffnung zwischengespeichert werden, dass der Benutzer viele Verweise auf sie erstellt. Abgesehen vom ersten Lesen der Datei werden nachfolgende Zugriffe auf den Arbeitsspeicher und nicht auf die Festplatte durchgeführt. Caching, wie das Puffern von Eingaben und Ausgaben, ist normalerweise für den Benutzer weitgehend transparent, und die Menge an Arbeitsspeicher, die zum Cachen von Dingen verwendet wird, kann sich in Abhängigkeit von der von Anwendungen usw. zugewiesenen RAM-Menge dynamisch ändern.
1 Technisch gesehen lesen die meisten Programme wahrscheinlich jeweils einen Teil der Eingabedaten, entweder explizit gepuffert oder implizit durch die Pufferung, die die Standard-E / A-Bibliotheken durchführen, und präsentieren diesen Teil dann zeilenweise im Code des Benutzers. Es ist viel effizienter, ein Vielfaches der Blockgröße der Festplatte zu lesen, als z. B. ein Zeichen gleichzeitig. Diese Blockgröße ist jedoch selten größer als eine Handvoll Kilobyte.
quelle
awk
,{ a[i++] = $0 }
würden alle Zeilen der Eingabedatei zum Array hinzufügena
. Möglicherweise möchten Sie auch die C-Funktion nachschlagenmmap()
, aber ihre Verwendung ist hier möglicherweise etwas unangebracht.sed
,,awk
und andere zeilenorientierte Programme lesen keine Zeile gleichzeitig in den Speicher, da Nur-Text-Dateien keinen Zeilenindex enthalten und Dateisystem-APIs und Low-Level-Speicherhardware einen oder mehrere "Sektoren" lesen (normalerweise 512) oder 1024 Bytes) gleichzeitig. Es würde mich wundern, wenn das Betriebssystem weniger als 8 KB in den Speicher einliest, bevor die erste Zeile verarbeitet wurde.sed
nur jeweils eine Zeile in den Speicher einliest, ist es erwähnenswert, dass das Betriebssystem kostenlosen RAM zum Zwischenspeichern von Dateien verwendet, damit auf diese schnell zugegriffen werden kann. Wenn Sie mitsed
einer kleineren Datei arbeiten, kann es vorkommen, dass das Betriebssystem die gesamte Datei im Arbeitsspeicher zwischenspeichert und der Vorgang vollständig im RAM ausgeführt wird. Siehe: en.wikipedia.org/wiki/Page_cacheNein. Obwohl es heutzutage fantastisch ist, RAM zu haben, gab es eine Zeit, in der RAM eine sehr begrenzte Ressource war (ich habe gelernt, auf einer VAX 11/750 mit 2 MB RAM zu programmieren) und das einzige, was im RAM aktiv war, waren ausführbare Dateien und Datenseiten von aktiven Prozessen und Dateidaten, die sich im Puffercache befanden.
Der Puffercache wurde geleert und die Datenseiten wurden ausgelagert. Und häufig zuweilen. Die schreibgeschützten ausführbaren Seiten wurden überschrieben und Seitentabellen markiert. Wenn das Programm diese Seiten erneut berührte, wurden sie aus dem Dateisystem ausgelagert. Die Daten wurden aus dem Swap ausgelagert. Wie oben erwähnt, hat die STDIO-Bibliothek Daten in Blöcken abgerufen und sie wurden vom Programm nach Bedarf abgerufen: fgetc, fgets, fread usw. Mit mmap kann eine Datei in den Adressraum eines Prozesses abgebildet werden, wie dies beispielsweise mit erfolgt ist Shared Library Objekte oder auch normale Dateien. Ja, Sie können ein gewisses Maß an Kontrolle haben, ob es sich im RAM befindet oder nicht (mlock), aber es geht nur so weit (siehe den Fehlercode-Abschnitt von mlock).
quelle