Articulo de referencia

modelo de memoria de Java

El modelo de memoria de Java describe cómo interactúan los hilos en el lenguaje de programación Java a través de la memoria. Junto con la descripción de la ejecución de código d...

El modelo de memoria de Java describe cómo interactúan los hilos en el lenguaje de programación Java a través de la memoria. Junto con la descripción de la ejecución de código de un solo hilo, el modelo de memoria proporciona la semántica del lenguaje de programación Java.

El modelo de memoria original de Java, desarrollado en 1995, fue ampliamente considerado defectuoso [ 1 ], lo que impedía muchas optimizaciones en tiempo de ejecución y no proporcionaba garantías suficientemente sólidas para la seguridad del código. Fue actualizado a través del Proceso de la Comunidad Java , como la Solicitud de Especificación Java 133 (JSR-133), que entró en vigor en 2004 para Tiger (Java 5.0) . [ 2 ] [ 3 ]

Contexto

El lenguaje y la plataforma de programación Java ofrecen capacidades de subprocesos . La sincronización entre subprocesos es notoriamente difícil para los desarrolladores; esta dificultad se agrava porque las aplicaciones Java pueden ejecutarse en una amplia gama de procesadores y sistemas operativos . Para poder comprender el comportamiento de un programa, los diseñadores de Java decidieron definir claramente los posibles comportamientos de todos los programas Java.

En las plataformas modernas, el código a menudo no se ejecuta en el orden en que fue escrito. El compilador, el procesador y el subsistema de memoria lo reordenan para lograr el máximo rendimiento. En arquitecturas multiprocesador , los procesadores individuales pueden tener sus propias cachés locales que no están sincronizadas con la memoria principal. Generalmente, no es deseable exigir que los hilos permanezcan perfectamente sincronizados entre sí, ya que esto resultaría demasiado costoso desde el punto de vista del rendimiento. Como resultado, diferentes hilos pueden observar diferentes valores de los mismos datos compartidos en un momento dado. [ 4 ]

En un entorno de un solo hilo, es fácil razonar sobre la ejecución del código. El enfoque típico requiere que el sistema implemente una semántica de ejecución en serie para cada hilo de forma aislada. Cuando un hilo se ejecuta, parecerá que todas las acciones realizadas por ese hilo ocurren en el orden en que aparecen en el programa, incluso si las acciones en sí ocurren fuera de orden.

Si un hilo ejecuta sus instrucciones fuera de orden, otro hilo podría percibir que dichas instrucciones se ejecutaron fuera de orden, incluso si esto no afecta la semántica del primer hilo. Por ejemplo, consideremos dos hilos con las siguientes instrucciones, que se ejecutan concurrentemente, donde las variables x e y se inicializan a 0:

Si no se realizan reordenamientos y la lectura de y en el Hilo  2 devuelve el valor  2, entonces la lectura posterior de x debería devolver el valor  1, ya que la escritura en x se realizó antes que la escritura en y. Sin embargo, si se reordenan las dos escrituras, entonces la lectura de y puede devolver el valor  2 y la lectura de x puede devolver el valor  0.

El Modelo de Memoria de Java (JMM) define el comportamiento permitido de los programas multihilo y, por lo tanto, describe cuándo son posibles dichas reordenaciones. Establece restricciones de tiempo de ejecución en la relación entre los hilos y la memoria principal para lograr aplicaciones Java consistentes y confiables. De esta manera, permite razonar sobre la ejecución del código en un entorno multihilo, incluso ante las optimizaciones realizadas por el compilador dinámico, el procesador o los procesadores y las cachés.

El modelo de memoria

Para la ejecución de un único hilo, las reglas son sencillas. La especificación del lenguaje Java exige que una máquina virtual Java observe la semántica de ejecución en serie dentro de cada hilo . El entorno de ejecución (que, en este caso, suele referirse al compilador dinámico, el procesador y el subsistema de memoria) puede introducir cualquier optimización de ejecución útil, siempre que se garantice que el resultado del hilo, de forma aislada, sea exactamente el mismo que si todas las instrucciones se hubieran ejecutado en el orden en que aparecieron en el programa (también llamado orden del programa). [ 5 ]

La principal salvedad es que la semántica de ejecución en serie no impide que distintos hilos tengan diferentes vistas de los datos. El modelo de memoria proporciona una guía clara sobre qué valores se pueden devolver al leer los datos. Las reglas básicas implican que las acciones individuales se pueden reordenar, siempre que no se viole la semántica de ejecución en serie del hilo, y las acciones que implican comunicación entre hilos, como la adquisición o liberación de un bloqueo , aseguran que las acciones que ocurren antes sean vistas por otros hilos que ven sus efectos. Por ejemplo, todo lo que ocurre antes de la liberación de un bloqueo se verá ordenado antes y será visible para todo lo que ocurre después de una adquisición posterior de ese mismo bloqueo. [ 6 ]

Matemáticamente, existe un orden parcial, denominado orden de precedencia, sobre todas las acciones realizadas por el programa. Este orden engloba el orden del programa; si una acción precede a otra en el orden del programa, también precederá a la otra en el orden de precedencia . Además, las liberaciones y adquisiciones posteriores de bloqueos forman aristas en el grafo de precedencia. Una lectura puede devolver el valor de una escritura si esta última es la última escritura en esa variable antes de la lectura a lo largo de alguna ruta en el orden de precedencia , o si la escritura no está ordenada con respecto a esa lectura en el orden de precedencia .

Impacto

El modelo de memoria de Java fue el primer intento de proporcionar un modelo de memoria integral para un lenguaje de programación popular. [ 7 ] Se justificó por la creciente prevalencia de sistemas concurrentes y paralelos, y la necesidad de proporcionar herramientas y tecnologías con una semántica clara para dichos sistemas. Desde entonces, la necesidad de un modelo de memoria ha sido más ampliamente aceptada, y se han proporcionado semánticas similares para lenguajes como C++ . [ 8 ]

Véase también

Referencias

  1. Pugh, William (2000). "El modelo de memoria de Java tiene fallas fatales" (PDF) . Concurrency: Practice and Experience . 12 (6): 445– 455. doi : 10.1002/1096-9128(200005)12:6 < 445::AID-CPE484 > 3.0.CO ; 2-A . Recuperado el 15 de julio de 2021 .
  2. Goetz, Brian (24 de febrero de 2004). "Corrigiendo el modelo de memoria de Java, parte 2" (PDF) . IBM . Consultado el 18 de octubre de 2010 .
  3. Jeremy Manson y Brian Goetz (febrero de 2004). "Preguntas frecuentes sobre JSR 133 (Modelo de memoria de Java)" . Consultado el 18 de octubre de 2010. El Modelo de memoria de Java describe qué comportamientos son válidos en código multihilo y cómo los hilos pueden interactuar a través de la memoria. Describe la relación entre las variables de un programa y los detalles de bajo nivel para almacenarlas y recuperarlas de la memoria o los registros en un sistema informático real. Lo hace de una manera que permite su correcta implementación con una amplia variedad de hardware y diversas optimizaciones del compilador.
  4. "Capítulo 17. Hilos y bloqueos" . Especificación del lenguaje Java, Oracle . Consultado el 9 de julio de 2025 .
  5. Manson, Jeremy. "Preguntas frecuentes sobre JSR-133" .
  6. "Capítulo 17. Hilos y bloqueos" . docs.oracle.com .
  7. Goetz, Brian (24 de febrero de 2004). "Corrigiendo el modelo de memoria de Java, parte 1" (PDF) . IBM . Consultado el 17 de febrero de 2008 .
  8. Boehm, Hans. "Hilos y modelo de memoria para C++" . Consultado el 8 de agosto de 2014 .
  • Teoría y práctica de Java: Corrección del modelo de memoria de Java, parte 1 - Un artículo que describe los problemas del modelo de memoria original de Java.
  • Teoría y práctica de Java: Corrección del modelo de memoria de Java, parte 2 - Explica los cambios que JSR 133 introdujo en el modelo de memoria de Java.
  • Pragmática del modelo de memoria de Java (transcripción)
  • El modelo de memoria de Java enlaza
  • Estructura interna de Java
  • Página web de JSR-133
  • Preguntas frecuentes sobre JSR-133
  • Guía de implementación de JSR-133