Что такое копирование при записи? - PullRequest
97 голосов
/ 10 марта 2009

Я хотел бы знать, что такое копирование при записи и для чего оно используется? Термин «массив копирования при записи» несколько раз упоминается в руководствах по Sun JDK, но я не понимаю, что это значит.

Ответы [ 6 ]

115 голосов
/ 10 марта 2009

Я собирался написать свое собственное объяснение, но эта статья в Википедии в значительной степени подводит итог.

Вот основная концепция:

Копирование при записи (иногда называемое «COW») - это стратегия оптимизации, используемая в компьютерном программировании. Основная идея заключается в том, что если несколько абонентов запрашивают ресурсы, которые изначально неразличимы, вы можете дать им указатели на один и тот же ресурс. Эту функцию можно поддерживать до тех пор, пока вызывающая сторона не попытается изменить свою «копию» ресурса, после чего создается настоящая личная копия, чтобы изменения не становились видимыми для всех остальных. Все это происходит прозрачно для абонентов. Основное преимущество заключается в том, что если вызывающая сторона никогда не вносит никаких изменений, не нужно создавать личную копию.

Также здесь приведено приложение общего использования COW:

Концепция COW также используется для поддержки мгновенного снимка на серверах баз данных, таких как Microsoft SQL Server 2005. Мгновенные снимки сохраняют статическое представление базы данных, сохраняя копию данных перед изменением при обновлении базовых данных. Мгновенные снимки используются для тестирования или для отчетов, зависящих от момента, и не должны использоваться для замены резервных копий.

50 голосов
/ 10 марта 2009

«Копировать при записи» означает более или менее то, на что это похоже: у каждого есть одна общая копия с одними и теми же данными до тех пор, пока они не будут записаны , а затем сделана копия. Обычно копирование при записи используется для решения проблем параллельного типа. Например, в ZFS блоки данных на диске размещаются при копировании при записи; пока нет изменений, вы сохраняете исходные блоки; изменение изменило только затронутые блоки. Это означает, что минимальное количество новых блоков выделено.

Эти изменения также обычно реализуются как транзакционные , т. Е. Они имеют свойства ACID. Это устраняет некоторые проблемы параллелизма, потому что тогда вы гарантируете, что все обновления являются атомарными.

9 голосов
/ 10 марта 2009

Я не буду повторять тот же ответ на Copy-on-Write. Я думаю, ответ Эндрю и ответ Чарли уже сделали это очень ясным. Я приведу вам пример из мира ОС, просто чтобы упомянуть, насколько широко эта концепция используется.

Мы можем использовать fork() или vfork() для создания нового процесса. vfork следует концепции копирования при записи. Например, дочерний процесс, созданный vfork, поделится сегментом данных и кода с родительским процессом. Это ускоряет время разветвления. Ожидается, что вы будете использовать vfork, если вы выполняете exec, а затем vfork. Таким образом, vfork создаст дочерний процесс, который поделится сегментом данных и кода со своим родителем, но когда мы вызовем exec, он загрузит образ нового исполняемого файла в адресное пространство дочернего процесса.

6 голосов
/ 24 сентября 2010

Просто в качестве другого примера, Mercurial использует копирование при записи , чтобы сделать клонирование локальных репозиториев действительно «дешевой» операцией.

Принцип тот же, что и в других примерах, за исключением того, что вы говорите о физических файлах, а не об объектах в памяти. Изначально клон - это не дубликат, а жесткая ссылка на оригинал. Когда вы изменяете файлы в клоне, копии записываются для представления новой версии.

2 голосов
/ 15 ноября 2015

Я нашел эту хорошую статью о zval в PHP, в которой также упоминается COW:

Копирование при записи (сокращенно «COW») - это прием, разработанный для экономии памяти. Он используется более широко в разработке программного обеспечения. Это означает, что PHP будет копировать память (или выделять новую область памяти) при записи в символ, если он уже указывал на zval.

1 голос
/ 10 марта 2009

Он также используется в Ruby Enterprise Edition как удобный способ экономии памяти.

...