¿Me gustaría saber qué es copiar y escribir y para qué se utiliza? El término "matriz de copia en escritura" se menciona varias veces en los tutoriales de Sun JDK, pero no entendí lo que significaba.
fuente
¿Me gustaría saber qué es copiar y escribir y para qué se utiliza? El término "matriz de copia en escritura" se menciona varias veces en los tutoriales de Sun JDK, pero no entendí lo que significaba.
Iba a escribir mi propia explicación, pero este artículo de Wikipedia lo resume bastante.
Aquí está el concepto básico:
Copiar en escritura (a veces denominado "VACA") es una estrategia de optimización utilizada en la programación de computadoras. La idea fundamental es que si varias personas que llaman solicitan recursos que inicialmente no se pueden distinguir, puede darles punteros al mismo recurso. Esta función se puede mantener hasta que la persona que llama intente modificar su "copia" del recurso, momento en el que se crea una copia privada verdadera para evitar que los cambios sean visibles para todos los demás. Todo esto sucede de manera transparente a las personas que llaman. La principal ventaja es que si la persona que llama nunca realiza modificaciones, no es necesario crear una copia privada.
También aquí hay una aplicación de un uso común de VACA:
El concepto COW también se utiliza en el mantenimiento de instantáneas instantáneas en servidores de bases de datos como Microsoft SQL Server 2005. Las instantáneas instantáneas conservan una vista estática de una base de datos al almacenar una copia de datos previa a la modificación cuando se actualizan los datos subyacentes. Las instantáneas instantáneas se usan para probar usos o informes dependientes del momento y no se deben usar para reemplazar las copias de seguridad.
clone()
implementafork()
: la memoria del proceso principal está COWed para el hijo."Copiar al escribir" significa más o menos lo que parece: todos tienen una sola copia compartida de los mismos datos hasta que se escribe , y luego se hace una copia. Por lo general, la copia en escritura se utiliza para resolver problemas de concurrencia. En ZFS , por ejemplo, los bloques de datos en el disco se asignan copia en escritura; mientras no haya cambios, conserva los bloques originales; un cambio solo cambió los bloques afectados. Esto significa que se asigna el número mínimo de nuevos bloques.
Estos cambios también suelen implementarse para ser transaccionales , es decir, tienen las propiedades ACID . Esto elimina algunos problemas de concurrencia, porque entonces está garantizado que todas las actualizaciones son atómicas.
fuente
A
. Proceso1
,2
,3
,4
cada uno desea hacer una copia del mismo y empezar a leerlo, en una "copia en escritura" sistema nada es copiado sin embargo, todo lo que todavía está leyendoA
. Ahora el proceso3
quiere hacer un cambio en su copiaA
, el proceso3
ahora hará una copiaA
y creará un nuevo bloque de datos llamadoB
. Proceso1
,2
,4
todavía está leyendo bloque deA
proceso3
es ahora la lecturaB
.A
debe crear una nueva copia. Si está preguntando qué sucede si aparece un proceso completamente nuevo y cambia,A
entonces mi explicación realmente no entra en suficientes detalles para eso. Eso sería de aplicación específica y requieren conocimientos sobre cómo desea que el resto de la aplicación al trabajo, tales como archivo \ bloqueo de datos, etc.No repetiré la misma respuesta en Copy-on-Write. Creo que la respuesta de Andrew y la respuesta de Charlie ya han dejado muy claro. Le daré un ejemplo del mundo del sistema operativo, solo para mencionar cuán ampliamente se usa este concepto.
Podemos usar
fork()
ovfork()
crear un nuevo proceso. vfork sigue el concepto de copia en escritura. Por ejemplo, el proceso hijo creado por vfork compartirá los datos y el segmento de código con el proceso padre. Esto acelera el tiempo de bifurcación. Se espera que use vfork si está ejecutando exec seguido de vfork. Entonces vfork creará el proceso hijo que compartirá datos y segmento de código con su padre pero cuando llamamos a exec, cargará la imagen de un nuevo ejecutable en el espacio de direcciones del proceso hijo.fuente
vfork
NO usa VACA. De hecho, si el niño escribe algo, puede provocar un comportamiento indefinido y no copiar páginas. De hecho, puedes decir que al revés es algo cierto. ¡VACA actúa comovfork
hasta que algo se modifica en el espacio compartido!Solo para proporcionar otro ejemplo, Mercurial utiliza la copia en escritura para hacer que la clonación de repositorios locales sea una operación realmente "barata".
El principio es el mismo que el de los otros ejemplos, excepto que se trata de archivos físicos en lugar de objetos en la memoria. Inicialmente, un clon no es un duplicado sino un enlace rígido al original. A medida que cambia los archivos en el clon, se escriben copias para representar la nueva versión.
fuente
Encontré este buen artículo sobre zval en PHP, que también mencionaba COW:
fuente
También se usa en Ruby 'Enterprise Edition' como una forma ordenada de ahorrar memoria.
fuente
Un buen ejemplo es Git, que utiliza una estrategia para almacenar blobs. ¿Por qué usa hashes? En parte porque estos son más fáciles de realizar, pero también porque simplifica la optimización de una estrategia COW. Cuando realiza una nueva confirmación con pocos cambios de archivos, la gran mayoría de los objetos y árboles no cambiarán. Por lo tanto, el commit, a través de varios punteros hechos de hashes, hará referencia a un grupo de objetos que ya existen, haciendo que el espacio de almacenamiento requerido para almacenar todo el historial sea mucho más pequeño.
fuente
Es un concepto de protección de memoria. En este compilador, se crea una copia adicional para modificar los datos en el niño y estos datos actualizados no se reflejan en los datos de los padres.
fuente
Aquí hay una implementación de Python de copia en escritura (COW) usando el patrón de diseño del decorador . Un objeto
Value
mutableCowValue
(el decorador) mantiene una referencia a un objeto inmutable . ElCowValue
objeto reenvía todas las solicitudes de lectura alValue
objeto inmutable e intercepta todas las solicitudes de escritura creando un nuevoValue
objeto inmutable con el estado correcto. ElCowValue
objeto debe copiarse superficialmente entre las variables para permitir compartir elValue
objeto.fuente