O que é copy-on-write?

Gostaria de saber o que é copy-on-write e para que é utilizado? O termo ‘array copy-on-write’ é mencionado várias vezes nos tutoriais do Sun JDK, mas eu não entendi o que isso significava.

Eu ia escrever minha própria explicação, mas este artigo da Wikipedia resume muito bem isso.

Aqui está o conceito básico:

Copy-on-write (às vezes chamado de “COW”) é uma estratégia de otimização usada na programação de computadores. A idéia fundamental é que, se vários chamadores solicitarem resources que são inicialmente indistinguíveis, você poderá fornecer indicadores para o mesmo recurso. Essa function pode ser mantida até que um chamador tente modificar sua “cópia” do recurso, no ponto em que uma cópia privada verdadeira é criada para impedir que as alterações se tornem visíveis para todos os outros. Tudo isso acontece de forma transparente para os chamadores. A principal vantagem é que, se um chamador nunca fizer modificações, nenhuma cópia particular precisará ser criada.

Também aqui é uma aplicação de um uso comum de vaca:

O conceito COW também é usado na manutenção de instantâneos instantâneos em servidores de bancos de dados como o Microsoft SQL Server 2005. Os instantâneos instantâneos preservam uma exibição estática de um database, armazenando uma cópia de dados pré-modificação quando os dados subjacentes são atualizados. Os instantâneos instantâneos são usados ​​para testar usos ou relatórios dependentes de momento e não devem ser usados ​​para replace backups.

“Copiar na gravação” significa mais ou menos o que parece: todos têm uma única cópia compartilhada dos mesmos dados até que sejam gravados e, depois, uma cópia é feita. Geralmente, copy-on-write é usado para resolver os tipos de problemas de simultaneidade. No ZFS, por exemplo, os blocos de dados no disco são alocados copy-on-write; contanto que não haja mudanças, você mantém os blocos originais; uma mudança mudou apenas os blocos afetados. Isso significa que o número mínimo de novos blocos é alocado.

Essas mudanças também são geralmente implementadas para serem transacionais , ou seja, elas possuem as propriedades ACID. Isso elimina alguns problemas de simultaneidade, porque então você está garantido que todas as atualizações são atômicas.

Apenas para fornecer outro exemplo, o Mercurial usa copy-on-write para tornar os repositorys locais de clonagem uma operação realmente “barata”.

O princípio é o mesmo dos outros exemplos, exceto que você está falando sobre arquivos físicos em vez de objects na memory. Inicialmente, um clone não é uma duplicata, mas um link rígido para o original. À medida que você altera os arquivos no clone, as cópias são gravadas para representar a nova versão.

Não vou repetir a mesma resposta em Copy-on-Write. Acho que a resposta de Andrew e a resposta de Charlie já deixaram isso bem claro. Vou dar um exemplo do mundo do sistema operacional, apenas para mencionar o quanto esse conceito é utilizado.

Podemos usar fork() ou vfork() para criar um novo processo. O vfork segue o conceito de copy-on-write. Por exemplo, o processo filho criado pelo vfork compartilhará os dados e o segmento de código com o processo pai. Isso acelera o tempo de bifurcação. Espera-se usar o vfork se você estiver executando exec seguido por vfork. Então vfork irá criar o processo filho que irá compartilhar dados e segmento de código com seu pai, mas quando nós chamamos exec, ele irá carregar a imagem de um novo executável no espaço de endereço do processo filho.

Ele também é usado no Ruby ‘Enterprise Edition’ como uma forma simples de economizar memory.

Eu encontrei este bom artigo sobre o zval no PHP, que também mencionou o COW:

Copy On Write (abreviado como ‘COW’) é um truque projetado para economizar memory. É usado mais geralmente em engenharia de software. Isso significa que o PHP irá copiar a memory (ou alocar nova região de memory) quando você escrever em um símbolo, se este já estiver apontando para um zval.