Gostaria de saber o que é copiar em gravação e para que é usado? O termo 'matriz de copiar na gravação' é mencionado várias vezes nos tutoriais do Sun JDK, mas eu não entendi o que isso significava.
fonte
Gostaria de saber o que é copiar em gravação e para que é usado? O termo 'matriz de copiar na gravação' é 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 bastante.
Aqui está o conceito básico:
A cópia na gravação (às vezes chamada de "COW") é uma estratégia de otimização usada na programação de computadores. A idéia fundamental é que, se vários chamadores solicitarem recursos inicialmente indistinguíveis, você poderá fornecer indicadores para o mesmo recurso. Essa função pode ser mantida até que um chamador tente modificar sua "cópia" do recurso, quando uma cópia privada verdadeira é criada para impedir que as alterações fiquem visíveis para todos os outros. Tudo isso acontece de forma transparente para os chamadores. A principal vantagem é que, se um chamador nunca fizer nenhuma modificação, nenhuma cópia privada será criada.
Também aqui está uma aplicação de um uso comum do COW:
O conceito COW também é usado na manutenção de instantâneos instantâneos em servidores de banco de dados como o Microsoft SQL Server 2005. Os instantâneos instantâneos preservam uma visão estática de um banco de dados, armazenando uma cópia de pré-modificação dos dados quando os dados subjacentes são atualizados. Instantâneos instantâneos são usados para testes de uso ou relatórios dependentes de momento e não devem ser usados para substituir backups.
clone()
implementafork()
- a memória do processo pai é COW para a criança."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, em seguida, uma cópia é feita. Geralmente, a cópia na gravação é usada para resolver os tipos de problemas de simultaneidade. No ZFS , por exemplo, os blocos de dados no disco são alocados na cópia; contanto que não haja alterações, você mantém os blocos originais; uma mudança alterou apenas os blocos afetados. Isso significa que o número mínimo de novos blocos é alocado.
Essas alterações também são geralmente implementadas para serem transacionais , ou seja, elas têm as propriedades ACID . Isso elimina alguns problemas de simultaneidade, porque você garante que todas as atualizações são atômicas.
fonte
A
. Processo1
,2
,3
,4
cada um quer fazer uma cópia do mesmo e começar a lê-lo, em uma "cópia na escrita" Sistema nada é copiado mas tudo ainda está lendoA
. Agora, o processo3
deseja alterar sua cópiaA
,3
agora o processo efetua uma cópiaA
e cria um novo bloco de dados chamadoB
. Processo1
,2
,4
ainda está lendo blocoA
processo3
está agora lendoB
.A
deve estar criando uma nova cópia. Se você está perguntando o que acontece se um processo totalmente novo surgir e mudarA
, minha explicação não entra em detalhes suficientes para isso. Isso seria implementação específica e exigem conhecimento sobre como você deseja que o resto da aplicação ao trabalho, tais como arquivo \ bloqueio de dados, etc.Não repetirei a mesma resposta em Copy-on-Write. Acho que a resposta de Andrew e a de Charlie já deixaram muito claro. Vou dar um exemplo do mundo do SO, apenas para mencionar o quão amplamente esse conceito é usado.
Podemos usar
fork()
ouvfork()
criar um novo processo. O vfork segue o conceito de cópia na gravação. Por exemplo, o processo filho criado pelo vfork compartilhará o segmento de dados e código com o processo pai. Isso acelera o tempo de bifurcação. Espera-se usar o vfork se você estiver executando exec seguido pelo vfork. Portanto, o vfork criará o processo filho que compartilhará os dados e o segmento de código com seu pai, mas quando chamamos exec, ele carregará a imagem de um novo executável no espaço de endereço do processo filho.fonte
vfork
NÃO usa VACA. De fato, se a criança escreve algo, pode resultar em comportamento indefinido e não copiar páginas! De fato, você pode dizer que o contrário é verdade. COW age comovfork
até que algo seja modificado no espaço compartilhado!Apenas para dar outro exemplo, o Mercurial usa a cópia na gravação para tornar a clonagem de repositórios locais 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 objetos na memória. Inicialmente, um clone não é uma duplicata, mas um vínculo físico com o original. Conforme você altera os arquivos no clone, as cópias são gravadas para representar a nova versão.
fonte
Encontrei este bom artigo sobre o zval no PHP, que também mencionou o COW:
fonte
Também é usado no Ruby 'Enterprise Edition' como uma maneira elegante de economizar memória.
fonte
Um bom exemplo é o Git, que usa uma estratégia para armazenar blobs. Por que ele usa hashes? Em parte porque essas são mais fáceis de executar, mas também porque simplifica a otimização de uma estratégia de COW. Quando você faz um novo commit com poucos arquivos, a grande maioria dos objetos e as árvores não são alteradas. Portanto, o commit, através de vários ponteiros feitos de hashes, fará referência a um monte de objetos que já existem, tornando o espaço de armazenamento necessário para armazenar todo o histórico muito menor.
fonte
É um conceito de proteção de memória. Neste compilador, cria uma cópia extra para modificar os dados no filho e esses dados atualizados não refletem nos dados dos pais.
fonte
A seguir, é apresentada uma implementação Python de copiar-em-gravar (COW), usando o padrão de design do decorador . Uma referência a um
Value
objeto imutável é mantida por umCowValue
objeto mutável (o decorador). OCowValue
objeto encaminha todas as solicitações de leitura para oValue
objeto imutável e intercepta todas as solicitações de gravação criando um novoValue
objeto imutável com o estado correto. OCowValue
objeto deve ser copiado superficialmente entre as variáveis para permitir o compartilhamento doValue
objeto.fonte