In modernen Systemen wird tatsächlich kein Speicher kopiert, nur weil ein Fork-Systemaufruf verwendet wird. In der Seitentabelle ist alles als schreibgeschützt markiert, so dass beim ersten Versuch, eine Falle in den Kernelcode zu schreiben, auftritt. Nur wenn der erste Schreibversuch des Prozesses erfolgt, wird kopiert.
Dies wird als Copy-on-Write bezeichnet.
Es kann jedoch erforderlich sein, auch den festgeschriebenen Adressraum zu verfolgen. Wenn zu dem Zeitpunkt, zu dem der Kernel eine Seite kopieren muss, kein Speicher oder Swap verfügbar ist, muss er einen Prozess beenden, um Speicher freizugeben. Dies ist nicht immer wünschenswert, daher ist es möglich, zu verfolgen, wie viel Speicher der Kernel zugewiesen hat.
Wenn der Kernel mehr als den verfügbaren Speicher + Swap festlegen würde, kann er beim Versuch, Fork aufzurufen, einen Fehlercode ausgeben. Wenn genug verfügbar ist, wird der Kernel nach dem Fork für beide Prozesse die volle virtuelle Größe des Elternprozesses übernehmen.
Keine Sorge, es macht eine faule Kopie (Copy-on-Write). Die virtuellen Speicheradressen beider Prozesse zeigen zunächst auf dieselben Seiten, aber wenn der gegabelte Prozess versucht, sie zu ändern, erstellt er tatsächlich eine physische Kopie der Seite (von da an befindet sich diese Seite an zwei Stellen in Ihrem RAM).
Beachten Sie, dass keiner der gemeldeten Speicherabdrücke Ihnen tatsächlich sagt, wie viel RAM der Prozess verwendet. Aufgrund von Auslagerungen, Speicherfreigabe und anderen Problemen mit virtuellem Speicher ist es unmöglich, dies mit Sicherheit zu wissen. Einige Teile des Speicherplatzes sind gemeinsam genutzte Bibliotheken (wo sollen sie gezählt werden?), einige beziehen sich auf Nicht-RAM-Speicher (andere Hardwaregeräte), einige werden derzeit ausgelagert, einige werden noch nicht kopiert (Copy-on-Write) und demnächst. Lesen Sie dies:
https://lwn.net/Articles/642202/
Es gibt eine Kernel-Einstellung
/proc/sys/vm/overcommit_memory
Zitat aus ausgezeichnetem Artikel:
Since 2.5.30 the values are: 0 (default): as before: guess about how much
overcommitment is reasonable, 1: never refuse any malloc(), 2: be precise
about the overcommit - never commit a virtual address space larger than swap
space plus a fraction overcommit_ratio of the physical memory. Here
/proc/sys/vm/overcommit_ratio (by default 50) is another user-settable
parameter. It is possible to set overcommit_ratio to values larger than 100.
(See also Documentation/vm/overcommit-accounting.)
Dies gilt sowohl für Gabeln als auch für reguläres Malloc. D.h. Wenn Sie es auf 0 setzen, wird der Fork beim Schreiben kopiert. Beim Schreiben kopieren bedeutet, dass nach dem Forken der App beide Kopien Speicherseiten gemeinsam nutzen, bis das Kind oder das Original beginnt, den Speicher zu ändern.
In den meisten Distributionen, die ich kenne, ist Overcommit 0. Aber wenn Sie es auf 2 setzen, werden alle Speicherseiten vollständig durch echten Speicher gesichert und in einigen Fällen unter hohem Speicherdruck stabiler sein, aber einige Programme (ich habe gitk gesehen), die darauf angewiesen sind bei Overcommits schlägt fehl.