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