コピーオンライト(COW)は暗黙的共有[1]やシャドウイング[2]とも呼ばれ、共有データを効率的に管理するためにプログラミングで使用されるリソース管理手法[3]です。複数のプログラムがデータを使用するときにすぐにデータをコピーするのではなく、変更を試みるまで同じデータがプログラム間で共有されます。変更がない場合はプライベートコピーは作成されないため、リソースが節約されます。[3]必要な場合にのみコピーが作成されるため、変更が発生したときに各プログラムが独自のバージョンを持つことが保証されます。この手法は、メモリ、ファイル、およびデータ構造によく適用されます。
仮想メモリ管理では
コピーオンライトは、オペレーティングシステムで主に使用され、複数のプロセスを実行するコンピュータの物理メモリを共有し、fork() システムコールを実装します。通常、新しいプロセスはメモリを変更せず、すぐに新しいプロセスを実行し、アドレス空間を完全に置き換えます。フォーク中に古いプロセスのメモリをすべてコピーしてすぐにコピーを破棄すると、プロセッサ時間とメモリが無駄になります。[4]
コピーオンライトは、ページ テーブルを使用して、特定のメモリページを読み取り専用としてマークし、そのページへの参照回数をカウントすることで、効率的に実装できます。これらのページにデータが書き込まれると、オペレーティング システムカーネルが書き込み試行をインターセプトし、コピーオンライト データで初期化された新しい物理ページを割り当てます。ただし、参照が 1 つしかない場合は割り当てをスキップできます。次に、カーネルは新しい (書き込み可能な) ページでページ テーブルを更新し、参照回数を減らして書き込みを実行します。新しい割り当てにより、あるプロセスのメモリの変更が別のプロセスには表示されないことが保証されます。[引用が必要]
コピーオンライト技術は、物理メモリの 1 ページをゼロで埋めておくことで、効率的なメモリ割り当てをサポートするように拡張できます。メモリが割り当てられると、返されるすべてのページはゼロのページを参照し、すべてコピーオンライトとしてマークされます。この方法では、データが書き込まれるまで物理メモリはプロセスに割り当てられないため、プロセスは物理メモリよりも多くの仮想メモリを予約し、メモリをまばらに使用できますが、仮想アドレス空間が不足するリスクがあります。組み合わせたアルゴリズムは、デマンドページングに似ています。[3]
コピーオンライトページはLinuxカーネルの同一ページマージ機能でも使用されます。[5]
ソフトウェアでは
COW はライブラリ、アプリケーション、システムコード でも使用されます。
例
C++標準ライブラリで提供される文字列クラスは、初期のC++98標準ではコピーオンライト実装を可能にするために特別に設計されていましたが、[6]新しいC++11標準ではそうではありません。[7]
std ::文字列x ( "こんにちは" );
std :: string y = x ; // x と y は同じバッファを使用します。
y += ", World!" ; // ここで y は別のバッファを使用しますが、x は引き続き同じ古いバッファを使用します。
PHPプログラミング言語では、参照を除くすべての型はコピーオンライトとして実装されています。たとえば、文字列と配列は参照によって渡されますが、変更されると、参照カウントがゼロでない場合は複製されます。これにより、代入時にコピーしたり不変にしたりすることによるパフォーマンスの問題なしに、値型として動作することができます。[8]
Qtフレームワークでは、多くの型がコピーオンライト (Qt の用語では「暗黙的に共有」) です。Qt は、内部参照カウンタを増減するためにアトミックな比較とスワップ操作を使用します。コピーは低コストであるため、Qt 型は、ミューテックスなどのロック機構を必要とせずに、複数のスレッドで安全に使用できます。したがって、COW の利点は、シングルスレッド システムとマルチスレッド システムの両方で有効です。[9]
コンピュータストレージ
COWは、 ZFS、Btrfs、ReFS、Bcachefsなどのファイルシステム[10]や、Microsoft SQL Serverなどの論理ボリューム管理やデータベースサーバーの基盤となるメカニズムとして使用されています。
従来のファイルシステムでは、ファイルの変更によって元のデータが上書きされます。COW では、変更が行われると、元のデータはそのままに、ファイルの新しいバージョンが作成されます。このアプローチにより、追加のスペースをあまり消費せずに特定の時点のファイルの状態をキャプチャするスナップショットなどの機能が可能になります。スナップショットは通常、変更されたデータのみを保存し、元のデータに近い状態に保たれます。ただし、これは増分バックアップの弱い形式と見なされており、完全バックアップの代わりにはなりません。[11]
参照
- フラッシュ時の割り当て
- Dirty COW – Linuxカーネルのコンピュータセキュリティの脆弱性
- フライウェイトパターン
- メモリ管理
- 永続的なデータ構造
- ウェアレベリング
参考文献
- ^ “Implicit Sharing”. Qt プロジェクト. 2024年2月8日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
- ^ Rodeh, Ohad (2008年2月1日). 「B-Trees, Shadowing, and Clones」(PDF) . ACM Transactions on Storage . 3 (4): 1. CiteSeerX 10.1.1.161.6863 . doi :10.1145/1326542.1326544. S2CID 207166167. 2017年1月2日時点の オリジナル(PDF)からアーカイブ。2023年11月10日閲覧。
- ^ abc ボヴェ、ダニエル・ピエール;マルコ・チェザーティ(2002年1月1日)。 Linux カーネルを理解する。オライリーメディア。 p. 295.ISBN 9780596002138. 2024年9月15日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
- ^ シルバーシャッツ、アブラハム、ガルビン、ピーター B.、ガニエ、グレッグ (2018)。オペレーティングシステムの概念(第 10 版)。ワイリー。pp. 120–123。ISBN 978-1119456339。
- ^ Abbas, Ali. 「The Kernel Samepage Merging Process」. alouche.net . 2016年8月8日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
{{cite web}}: CS1 メンテナンス: 不適切 URL (リンク) - ^ マイヤーズ、スコット(2012)。効果的なSTL。アディソン・ウェズリー。pp. 64–65。ISBN 9780132979184。
- ^ 「Concurrency Modifications to Basic String」。オープンスタンダード。2023年11月10日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
- ^ Pauli, Julien; Ferrara, Anthony; Popov, Nikita (2013). 「メモリ管理」. PhpInternalsBook.com . 2023年11月10日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
- ^ 「スレッドと暗黙的に共有されるクラス」。Qt プロジェクト。2023 年 12 月 3 日時点のオリジナルよりアーカイブ。2023年11 月 10 日閲覧。
- ^ Kasampalis, Sakis (2010). 「Copy-on-Write ベースのファイルシステムのパフォーマンス分析と実装」(PDF)。p. 19。2024年 5 月 5 日時点のオリジナルよりアーカイブ(PDF) 。2023 年11 月 10 日閲覧。
- ^ Chien, Tim. 「スナップショットはバックアップではありません」。Oracle.com。Oracle。2023年11月10日時点のオリジナルよりアーカイブ。2023年11月10日閲覧。
