Cualquier concepto de memoria compartida en Java

AFAIK, la memoria en Java se basa en un montón del cual la memoria se asigna dinámicamente a los objetos y no existe un concepto de memoria compartida.

Si no existe un concepto de memoria compartida, entonces la comunicación entre progtwigs Java debería consumir mucho tiempo. En C, donde la comunicación entre procesos es más rápida a través de la memoria compartida en comparación con otros modos de comunicación.

Corrígeme si estoy equivocado. Además, ¿cuál es la forma más rápida de que 2 progenitores Java hablen entre sí?

Como no existe una API oficial para crear un segmento de memoria compartida, debe recurrir a una biblioteca auxiliar / DDL y JNI para usar la memoria compartida para que dos procesos Java se comuniquen entre sí.

En la práctica, esto rara vez es un problema ya que Java admite subprocesos, por lo que puede tener dos “progtwigs” que se ejecutan en la misma máquina virtual de Java. Esos compartirán el mismo montón, por lo que la comunicación será instantánea. Además, no puede obtener errores debido a problemas con el segmento de memoria compartida.

Hay al menos 2 formas de hacerlo: RAM Drive o Apache APR .

Detalles aquí y aquí con algunas medidas de rendimiento.

Vale la pena mirar el proyecto Java Chronicle de Peter Lawrey.

Estas son algunas pruebas que he hecho hace un tiempo comparando varias opciones de almacenamiento dynamic y almacenamiento dynamic.

La memoria compartida a veces es rápida. A veces no es así – daña las memorias caché de la CPU y la sincronización es a menudo un dolor (y si se basa en mutexes y tal, puede ser una gran penalización de rendimiento).

Barrelfish es un sistema operativo que demuestra que el IPC que utiliza el envío de mensajes es realmente más rápido que la memoria compartida a medida que aumenta el número de núcleos (en architectures convencionales X86 y en las cosas NUMA NUCA más exóticas que se suponía que tenía como objective).

Por lo tanto, su suposición de que la memoria compartida es rápida necesita pruebas para su escenario particular y su hardware de destino. ¡No es una suposición sonora genérica estos días!

Una cosa a tener en cuenta es usar archivos mapeados en memoria , utilizando la clase FileChannel de Java NIO o similar (ver el método map ()). Hemos utilizado esto con mucho éxito para comunicarnos (en nuestro caso, de una sola dirección) entre un proceso Java y uno C nativo en la misma máquina.

Admitiré que no soy un experto en sistemas de archivos (afortunadamente tenemos uno en el equipo!) Pero el rendimiento para nosotros es absolutamente increíblemente rápido: efectivamente estás tratando una sección de la memoria caché de la página como un archivo y leyendo + escribiendo a directamente sin la sobrecarga de las llamadas al sistema. No estoy seguro acerca de las garantías y la coherencia: hay métodos en Java para forzar los cambios que se escriben en el archivo, lo que implica que (a veces, normalmente, normalmente, normalmente, no seguro) se escriben en el archivo subyacente real. (¿Algo? ¿Muy? ¿Extremadamente?) perezosamente, lo que significa que una proporción del tiempo es básicamente solo un segmento de memoria compartida.

En teoría, según entiendo, los archivos mapeados en memoria PUEDEN estar respaldados por un segmento de memoria compartida (creo que son solo manejadores de archivos), pero no conozco una forma de hacerlo en Java sin JNI.

Hay un par de tecnologías comparables que puedo pensar:

  1. Hace unos años existía una tecnología llamada JavaSpaces, pero que en realidad nunca pareció afianzarse, una pena si me preguntas.
  2. Hoy en día existen las tecnologías de caché distribuida, como Coherence y Tangosol .

Lamentablemente, ninguno de los dos tendrá la velocidad correcta de memoria compartida, pero sí los problemas de acceso simultáneo, etc.

La forma más fácil de hacerlo es tener dos procesos instanciando el mismo archivo mapeado en memoria. En la práctica, compartirán el mismo espacio de memoria fuera de montón. Puede tomar la dirección física de esta memoria y usar sun.misc.Unsafe para escribir / leer primitivas. Admite concurrencia a través de los métodos putXXXVolatile / getXXXVolatile. Eche un vistazo a CoralQueue que ofrece IPC de manera sencilla, así como también comunicación entre hilos dentro de la misma JVM.

Descargo de responsabilidad : soy uno de los desarrolladores de CoralQueue.

Similar a Java Chronicle de Peter Lawrey, puedes probar Jocket .

También utiliza un MappedByteBuffer pero no persiste ningún dato y está destinado a ser utilizado como un reemplazo directo a Socket / ServerSocket.

La latencia de ida y vuelta para un ping-pong de 1kB es de alrededor de medio microsegundo.

MappedBus ( http://github.com/caplogic/mappedbus ) es una biblioteca que agregué en github que permite IPC entre múltiples (más de dos) procesos / JVM de Java mediante el envío de mensajes.

El transporte puede ser un archivo mapeado en memoria o memoria compartida. Para usarlo con la memoria compartida, simplemente siga los ejemplos en la página de github, pero apunte a los lectores / escritores a un archivo en “/ dev / shm /”.

Es de código abierto y la implementación se explica completamente en la página de github.

La información proporcionada por Cowan es correcta. Sin embargo, incluso la memoria compartida no siempre parecerá ser idéntica en varios hilos (y / o procesos) al mismo tiempo. La razón subyacente clave es el modelo de memoria de Java (que se basa en el modelo de memoria de hardware). Consulte ¿Pueden los hilos múltiples ver escrituras en un ByteBuffer mapeado directo en Java? para una discusión bastante útil del tema.

Intereting Posts