web-dev-qa-db-fra.com

Tout concept de mémoire partagée en Java

Autant que je sache, la mémoire en Java est basée sur le tas à partir duquel la mémoire est allouée dynamiquement aux objets et il n’existe aucun concept de mémoire partagée.

S'il n'y a pas de concept de mémoire partagée, la communication entre les programmes Java devrait prendre beaucoup de temps. En C, la communication entre processus est plus rapide via la mémoire partagée par rapport aux autres modes de communication.

Corrige moi si je me trompe. Aussi, quel est le moyen le plus rapide pour 2 progs Java de se parler.

21
emkrish

Comme il n'y a pas d'API officielle pour créer un segment de mémoire partagée, vous devez recourir à une bibliothèque d'assistance/DDL et à JNI pour utiliser la mémoire partagée afin que deux processus Java se parlent.

En pratique, cela pose rarement un problème puisque Java prend en charge les threads, vous pouvez donc avoir deux "programmes" exécutés dans la même machine virtuelle Java. Ceux-ci partageront le même tas, la communication sera donc instantanée. De plus, vous ne pouvez pas obtenir d'erreurs en raison de problèmes liés au segment de mémoire partagée.

14
Aaron Digulla

Il y a au moins 2 façons de le faire - RAM Drive ou Apache APR .

Détails ici et ici avec quelques mesures de performance.

22
Ashwin Jayaprakash

Le projet Java Chronicle de Peter Lawrey mérite d'être examiné.

Ce sont quelques tests que j'avais fait il y a un moment en comparant diverses options off-tas et on-tas.

9
Ashwin Jayaprakash

Une chose à regarder consiste à utiliser les fichiers mappés en mémoire , à l’aide de FileChannel class de Java NIO ou similaire (voir la méthode map ()). Nous avons utilisé cette méthode avec succès pour communiquer (dans notre cas, à sens unique) entre un processus Java et un processus C natif sur le même ordinateur.

J'admets que je ne suis pas un expert en systèmes de fichiers (heureusement que nous en avons un parmi le personnel!), Mais la performance est extrêmement rapide - nous traitons une section de la cache de pages comme un fichier et lisons + écrivons directement sans la surcharge des appels système. Je ne suis pas sûr des garanties et de la cohérence - il existe des méthodes en Java pour forcer l'écriture des modifications dans le fichier, ce qui implique qu'elles sont (parfois? Généralement? Généralement? Normalement? Normalement? Pas sûr) dans le fichier sous-jacent réel (un peu? très? extrêmement?) paresseusement, ce qui signifie qu’une partie du temps c’est essentiellement un segment de mémoire partagée. 

En théorie, si je comprends bien, les fichiers mappés en mémoire PEUVENT en réalité être sauvegardés par un segment de mémoire partagée (ce ne sont que des descripteurs de fichiers, je pense), mais je ne connais pas de moyen de le faire en Java sans JNI.

8
Cowan

La mémoire partagée est parfois rapide. Parfois, cela bloque les caches de processeur et la synchronisation est souvent pénible (et si elle repose sur des mutex et autres, elle peut être un inconvénient majeur en termes de performances).

Barrelfish est un système d'exploitation qui montre que IPC le passage de messages est en réalité plus rapide que la mémoire partagée lorsque le nombre de cœurs augmente (sur les architectures X86 classiques ainsi que sur les solutions plus exotiques NUMA NUCA ' J'imagine qu'il s'agissait d'un ciblage).

Par conséquent, votre hypothèse selon laquelle la mémoire partagée est rapide nécessite des tests pour votre scénario particulier et pour votre matériel cible. Ce n'est pas une hypothèse sonore générique de nos jours!

7
Will

Il y a quelques technologies comparables auxquelles je peux penser:

  1. Il y a quelques années, il existait une technologie appelée JavaSpaces mais qui ne semblait jamais vraiment s'imposer, dommage si vous me le demandez.
  2. De nos jours, il existe les technologies de cache distribué, telles que Coherence et Tangosol .

Malheureusement, ni l'un ni l'autre n'auront la vitesse de mémoire partagée suffisante, mais ils traitent des problèmes d'accès simultané, etc.

4
Nick Holt

Pour ce faire, le plus simple consiste à faire en sorte que deux processus instancient le même fichier mappé en mémoire. En pratique, ils partageront le même espace mémoire vierge. Vous pouvez récupérer l'adresse physique de cette mémoire et utiliser Sun.misc.Unsafe pour écrire/lire des primitives. Il prend en charge la concurrence via les méthodes putXXXVolatile/getXXXVolatile. Jetez un coup d’œil sur CoralQueue qui offre IPC facilement ainsi qu’une communication inter-thread au sein de la même machine virtuelle.

Disclaimer : Je suis l'un des développeurs de CoralQueue.

2
rdalmeida

MappedBus ( http://github.com/caplogic/mappedbus ) est une bibliothèque ajoutée sur github qui active IPC entre plusieurs (plus de deux) processus Java/JVM par transmission de messages .

Le transport peut être un fichier mappé en mémoire ou une mémoire partagée. Pour l'utiliser avec la mémoire partagée, suivez simplement les exemples de la page github, mais dirigez les lecteurs/écrivains vers un fichier sous "/ dev/shm /".

C'est open source et l'implémentation est entièrement expliquée sur la page github.

1
MikaelJ

Semblable à Java Chronicle de Peter Lawrey, vous pouvez essayer Jocket .

Il utilise également un MappedByteBuffer mais ne conserve aucune donnée et est destiné à être utilisé en remplacement direct de Socket/ServerSocket.

La latence aller-retour pour un ping-pong de 1 Ko est d'environ une demi-microseconde.

1
pcdv

Les informations fournies par Cowan sont correctes. Cependant, même la mémoire partagée ne semblera pas toujours identique dans plusieurs threads (et/ou processus) en même temps. La principale raison sous-jacente est le modèle de mémoire Java (qui repose sur le modèle de mémoire matérielle). Voir Plusieurs threads peuvent-ils voir des écritures sur un ByteBuffer mappé directement en Java? pour une discussion assez utile sur le sujet.

0
Peter Schaeffer