コピーオンライト(COW)は、暗黙的共有[1]やシャドウイング[2]とも呼ばれ、プログラミングにおいて共有データを効率的に管理するために使用されるリソース管理手法[3]です。複数のプログラムがデータを使用する際にデータをすぐにコピーするのではなく、プログラム間で同じデータが共有され、変更が試みられるまで共有されます。変更がない場合はプライベートコピーは作成されないため、リソースを節約できます。[3]コピーは必要な場合にのみ作成されるため、変更が発生したときに各プログラムが独自のバージョンを持つことが保証されます。この手法は、メモリ、ファイル、データ構造によく適用されます。
コピーオンライトは、オペレーティングシステムにおいて、複数のプロセスを実行するコンピュータの物理メモリを共有する、 fork()システムコールの実装において主に使用されています。通常、新しいプロセスはメモリを一切変更せず、直ちに新しいプロセスを実行し、アドレス空間を完全に置き換えます。フォーク中に古いプロセスのメモリ全体をコピーし、そのコピーをすぐに破棄するのは、プロセッサ時間とメモリの無駄です。[4]
コピーオンライトは、ページテーブルを用いて、特定のメモリページを読み取り専用としてマークし、そのページへの参照回数を記録することで効率的に実装できます。これらのページにデータが書き込まれると、オペレーティングシステムのカーネルは書き込み試行を傍受し、コピーオンライトデータで初期化された新しい物理ページを割り当てます。ただし、参照が1つしかない場合は、この割り当てを省略できます。カーネルは、新しい(書き込み可能な)ページでページテーブルを更新し、参照回数を減らしてから書き込みを実行します。この新しい割り当てにより、あるプロセスのメモリへの変更が別のプロセスには反映されなくなります。[要出典]
コピーオンライト技術は、物理メモリの1ページをゼロで埋めておくことで、効率的なメモリ割り当てをサポートするように拡張できます。メモリが割り当てられると、返されるすべてのページはゼロのページを参照し、すべてコピーオンライトとしてマークされます。これにより、データが書き込まれるまで物理メモリはプロセスに割り当てられないため、プロセスは物理メモリよりも多くの仮想メモリを予約し、メモリを分散して使用できますが、仮想アドレス空間が不足するリスクがあります。この組み合わせのアルゴリズムは、デマンドページングに似ています。[3]
コピーオンライトページはLinuxカーネルの同一ページマージ機能でも使用されます。[5]
COW はライブラリ、アプリケーション、システムコード でも使用されます。
C++標準ライブラリで提供される文字列クラスは、初期のC++98標準ではコピーオンライト実装を可能にするように特別に設計されていましたが、[6]新しいC++11標準ではそうではありません。[7]
std :: string x ( "こんにちは" );
std :: string y = x ; // x と y は同じバッファを使用します。
y += ", World!" ; // ここで y は別のバッファを使用しますが、x は引き続き同じ古いバッファを使用します。
PHPプログラミング言語では、参照型を除くすべての型はコピーオンライトとして実装されています。例えば、文字列と配列は参照渡しされますが、変更時に参照カウントが0以外の場合は複製されます。これにより、代入時のコピーや不変化に伴うパフォーマンス上の問題が発生することなく、値型として扱うことができます。[8]
Qtフレームワークでは、多くの型がコピーオンライト(Qtの用語では「暗黙的に共有」)です。Qtは、内部参照カウンタの増分または減分にアトミックな比較・交換操作を使用します。コピーのコストが低いため、Qtの型はミューテックスなどのロック機構を必要とせずに、複数のスレッドで安全に使用できます。したがって、COWの利点はシングルスレッドシステムとマルチスレッドシステムの両方で有効です。[9]
COWは、 ZFS、Btrfs、[10] ReFS、Bcachefsなどのファイルシステム、およびMicrosoft SQL Serverなどの論理ボリューム管理やデータベースサーバーの基盤となるメカニズムとして使用されています。
従来のファイルシステムでは、ファイルを変更すると元のデータブロックがその場で上書きされます。一方、コピーオンライト(COW)ファイルシステムでは、元のブロックは変更されません。ファイルの一部が変更されると、影響を受けたブロックのみが新しい場所に書き込まれ、メタデータはそれらのブロックを指すように更新されます。これにより、元のバージョンは不要になるまで保存されます。このアプローチにより、追加のスペースをあまり消費することなく、特定の時点のファイルの状態をキャプチャするスナップショットなどの機能が可能になります。スナップショットは通常、変更されたデータのみを保存し、元のデータに近い状態に保たれます。しかし、これは増分バックアップの弱い形式と考えられており、完全バックアップの代わりにはなりません。[11]
新しいコンテナを迅速に作成して起動するために、 OS レベルの仮想化を行うコンテナ エンジンは、多くの場合、ブロック レベルのコピー オン ライト (上記で説明したとおり) またはファイル レベルのコピー オン ライトのいずれかで、ストレージ内でコピー オン ライトを実行します。
一部のファイルシステムは、ユニオンマウントの一部としてファイルレベルのコピーオンライトをサポートしていますが、これにはOverlayFS、aufs、GlusterFS、UnionFS が含まれます[12]。