Ich möchte wissen, was Copy-on-Write ist und wofür es verwendet wird. Der Begriff "Copy-on-Write-Array" wird in den Sun JDK-Tutorials mehrmals erwähnt, aber ich habe nicht verstanden, was er bedeutet.
quelle
Ich möchte wissen, was Copy-on-Write ist und wofür es verwendet wird. Der Begriff "Copy-on-Write-Array" wird in den Sun JDK-Tutorials mehrmals erwähnt, aber ich habe nicht verstanden, was er bedeutet.
Ich wollte meine eigene Erklärung schreiben, aber dieser Wikipedia-Artikel fasst es ziemlich gut zusammen.
Hier ist das Grundkonzept:
Copy-on-Write (manchmal auch als "COW" bezeichnet) ist eine Optimierungsstrategie, die bei der Computerprogrammierung verwendet wird. Die Grundidee ist, dass wenn mehrere Anrufer nach Ressourcen fragen, die anfangs nicht unterscheidbar sind, Sie ihnen Zeiger auf dieselbe Ressource geben können. Diese Funktion kann beibehalten werden, bis ein Aufrufer versucht, seine "Kopie" der Ressource zu ändern. Zu diesem Zeitpunkt wird eine echte private Kopie erstellt, um zu verhindern, dass die Änderungen für alle anderen sichtbar werden. All dies geschieht transparent für die Anrufer. Der Hauptvorteil besteht darin, dass keine private Kopie erstellt werden muss, wenn ein Anrufer niemals Änderungen vornimmt.
Auch hier ist eine Anwendung einer allgemeinen Verwendung von COW:
Das COW-Konzept wird auch bei der Wartung von Sofort-Snapshots auf Datenbankservern wie Microsoft SQL Server 2005 verwendet. Instant-Snapshots behalten eine statische Ansicht einer Datenbank bei, indem eine Kopie der Daten vor der Änderung gespeichert wird, wenn die zugrunde liegenden Daten aktualisiert werden. Sofortige Snapshots werden zum Testen von Anwendungen oder momentabhängigen Berichten verwendet und sollten nicht zum Ersetzen von Sicherungen verwendet werden.
clone()
der Implementierungfork()
- der Speicher des übergeordneten Prozesses ist für das untergeordnete Element COWed."Beim Schreiben kopieren" bedeutet mehr oder weniger, wie es sich anhört: Jeder hat eine einzige gemeinsam genutzte Kopie derselben Daten, bis sie geschrieben werden , und dann wird eine Kopie erstellt. Normalerweise wird Copy-on-Write verwendet, um Probleme mit Parallelität zu lösen. In ZFS werden beispielsweise Datenblöcken auf der Festplatte Copy-on-Write zugewiesen. Solange keine Änderungen vorgenommen wurden, behalten Sie die ursprünglichen Blöcke bei. Eine Änderung hat nur die betroffenen Blöcke geändert. Dies bedeutet, dass die Mindestanzahl neuer Blöcke zugewiesen wird.
Diese Änderungen werden normalerweise auch transaktional implementiert , dh sie haben die ACID- Eigenschaften. Dadurch werden einige Parallelitätsprobleme beseitigt, da dann garantiert wird, dass alle Updates atomar sind.
quelle
A
. Verfahren1
,2
,3
,4
jeder möchte eine Kopie davon machen und beginnen , es zu lesen, in einem „Copy - on - Write“ System nichts kopiert noch alles noch zu lesenA
. Jetzt3
möchte der Prozess eine Änderung an seiner Kopie vornehmen. DerA
Prozess erstellt3
nun tatsächlich eine KopieA
und erstellt einen neuen Datenblock mit dem NamenB
. Prozess1
,2
,4
sind Block nochA
Lesevorgang3
ist jetzt liestB
.A
sollte eine neue Kopie erstellen. Wenn Sie sich fragen, was passiert, wenn ein völlig neuer Prozess eintritt und sich ändert, gehtA
meine Erklärung dafür nicht wirklich ins Detail. Das wäre implementierungsspezifisch und erfordert Kenntnisse darüber, wie der Rest der Implementierung funktionieren soll, wie z. B. Sperren von Dateien \ Daten usw.Ich werde nicht die gleiche Antwort auf Copy-on-Write wiederholen. Ich denke, Andrews Antwort und Charlies Antwort haben es bereits sehr deutlich gemacht. Ich werde Ihnen ein Beispiel aus der OS-Welt geben, um nur zu erwähnen, wie weit verbreitet dieses Konzept ist.
Wir können einen neuen Prozess verwenden
fork()
odervfork()
erstellen. vfork folgt dem Konzept des Copy-on-Write. Beispielsweise teilt der von vfork erstellte untergeordnete Prozess das Daten- und Codesegment mit dem übergeordneten Prozess. Dies beschleunigt die Gabelzeit. Es wird erwartet, dass vfork verwendet wird, wenn Sie exec gefolgt von vfork ausführen. Daher erstellt vfork den untergeordneten Prozess, der Daten und Codesegmente mit seinem übergeordneten Prozess teilt. Wenn wir jedoch exec aufrufen, wird das Image einer neuen ausführbaren Datei in den Adressraum des untergeordneten Prozesses geladen.quelle
vfork
verwendet KEINE KUH. In der Tat, wenn das Kind etwas schreibt, kann es zu undefiniertem Verhalten und nicht zum Kopieren von Seiten führen !! In der Tat kann man sagen, dass der umgekehrte Weg etwas wahr ist. COW verhält sich so, als obvfork
etwas im gemeinsamen Raum verändert wird!Um nur ein weiteres Beispiel zu nennen: Mercurial verwendet Copy-on-Write , um das Klonen lokaler Repositorys zu einem wirklich "billigen" Vorgang zu machen.
Das Prinzip ist das gleiche wie in den anderen Beispielen, außer dass Sie von physischen Dateien anstelle von Objekten im Speicher sprechen. Ein Klon ist zunächst kein Duplikat, sondern eine feste Verbindung zum Original. Wenn Sie Dateien im Klon ändern, werden Kopien geschrieben, um die neue Version darzustellen.
quelle
Ich habe diesen guten Artikel über zval in PHP gefunden, in dem auch COW erwähnt wurde:
quelle
Es wird auch in Ruby 'Enterprise Edition' verwendet, um Speicherplatz zu sparen.
quelle
Ein gutes Beispiel ist Git, das eine Strategie zum Speichern von Blobs verwendet. Warum werden Hashes verwendet? Zum Teil, weil diese einfacher durchzuführen sind, aber auch, weil es einfacher ist, eine COW-Strategie zu optimieren. Wenn Sie mit wenigen Dateiänderungen ein neues Commit durchführen, ändert sich die überwiegende Mehrheit der Objekte und Bäume nicht. Daher verweist das Commit durch verschiedene Zeiger aus Hashes auf eine Reihe bereits vorhandener Objekte, wodurch der zum Speichern des gesamten Verlaufs erforderliche Speicherplatz viel kleiner wird.
quelle
Es ist ein Speicherschutzkonzept. In diesem Compiler wird eine zusätzliche Kopie erstellt, um Daten im untergeordneten Element zu ändern. Diese aktualisierten Daten spiegeln sich nicht in den übergeordneten Daten wider.
quelle
Hier folgt eine COW-Python-Implementierung (Copy-on-Write) unter Verwendung des Decorator-Entwurfsmusters . Ein Verweis auf ein unveränderliches
Value
Objekt wird von einem veränderlichenCowValue
Objekt (dem Dekorateur) gehalten. DasCowValue
Objekt leitet alle Leseanforderungen an das unveränderlicheValue
Objekt weiter und fängt alle Schreibanforderungen ab, indem es ein neues unveränderlichesValue
Objekt mit dem richtigen Status erstellt. DasCowValue
Objekt muss flach zwischen Variablen kopiert werden, damit dasValue
Objekt gemeinsam genutzt werden kann.quelle