Tout concept de mémoire partagée en Java
AFAIK, la mémoire en Java est basée sur un tas à partir duquel la mémoire est attribuée aux objets de façon dynamique et il n'y a pas de concept de mémoire partagée.
S'il n'y a pas de concept de mémoire partagée, alors la communication entre les programmes Java devrait être longue. En C, où la communication inter-processus est plus rapide via la mémoire partagée par rapport aux autres modes de communication.
corrigez-moi si je me trompe. Aussi Quel est le moyen le plus rapide pour 2 Java progs à parler les uns aux autres.
10 réponses
Puisqu'il n'y a pas D'API officielle pour créer un segment de mémoire partagée, vous devez recourir à une bibliothèque helper/DDL et JNI pour utiliser la mémoire partagée afin d'avoir deux processus Java qui se parlent.
dans la pratique, C'est rarement un problème puisque Java supporte les threads, donc vous pouvez avoir deux" programmes " exécutés dans la même VM Java. Ils partageront le même tas, donc la communication sera instantanée. De plus, vous ne pouvez pas avoir d'erreurs à cause de problèmes avec le segment de mémoire partagée.
il y a au moins 2 façons de le faire - RAM Drive ou Apache APR .
Peter Lawrey Java Chronique le projet est intéressant de regarder.
ce sont des certains tests que j'avais fait il y a longtemps la comparaison de différents hors-tas et des tas d'options.
la mémoire partagée est parfois rapide. Parfois son pas-il blesse les caches CPU et la synchronisation est souvent une douleur (et si elle s'appuie sur des mutex et autres, peut être une pénalité de performance majeure).
Barrelfish est un système d'exploitation qui démontre que la CIB utilisant le passage de messages est en fait plus rapide que la mémoire partagée au fur et à mesure que le nombre de cœurs augmente (sur les architectures x86 conventionnelles ainsi que les trucs NUMA NUCA plus exotiques que vous suppose que c'était de ciblage).
donc votre hypothèse que la mémoire partagée est un test rapide a besoin pour votre scénario particulier et sur votre matériel cible. Ce n'est pas une hypothèse de son générique ces jours-ci!
une chose à regarder est d'utiliser memory-mapped files , en utilisant Java NIO FileChannel classe ou similaire (voir la méthode map ()). Nous l'avons utilisé avec beaucoup de succès pour communiquer (dans notre cas à Sens Unique) entre un processus Java et un processus C natif sur la même machine.
j'admets que je ne suis pas un expert en systèmes de fichiers (heureusement que nous en avons un dans le staff!) mais la performance pour nous est absolument flamboyante rapide -- effectivement vous êtes traiter une section du cache de page comme un fichier et y lire + y écrire directement sans passer par les appels système. Je ne suis pas sûr des garanties et de la cohérence -- il y a des méthodes en Java pour forcer les changements à être écrits dans le fichier, ce qui implique qu'ils le sont (parfois? typiquement? habituellement? normalement? pas sûr) écrit dans le fichier sous-jacent (un peu? très? extrêmement?) paresseusement, ce qui signifie qu'une certaine proportion du temps c'est essentiellement juste un segment de mémoire partagée.
en théorie, si j'ai bien compris, les fichiers mappés en mémoire peuvent en fait être sauvegardés par un segment de mémoire partagée (ce ne sont que des poignées de fichiers, je pense), mais je ne suis pas au courant d'une façon de le faire en Java sans JNI.
il y a quelques technologies comparables auxquelles je peux penser:
- il y a quelques années, il y avait une technologie appelée JavaSpaces mais qui n'a jamais vraiment semblé s'imposer, une honte si vous me demandez.
- de nos jours il y a les technologies de cache distribuées, des choses comme cohérence et Tangosol .
malheureusement ni l'un ni l'autre aura la bonne vitesse de sortie de la mémoire partagée, mais ils traitent des questions d'accès simultané, etc.
la façon la plus facile de faire cela est d'avoir deux processus instancier le même fichier mappé en mémoire. En pratique, ils partageront le même espace mémoire hors tas. Vous pouvez saisir l'adresse physique de cette mémoire et l'utilisation sun.misc.Unsafe
pour écrire/lire des primitives. Il prend en charge la concurrence par les méthodes putXXXVolatile/getXXXVolatile. Jetez un coup d'oeil sur CoralQueue qui offre une IPC facilement ainsi que la communication inter-thread à l'intérieur de la même JVM.
clause de non-responsabilité : je suis un des développeurs de CoralQueue.
similaire au Java Chronicle de Peter Lawrey, vous pouvez essayer Jocket .
il utilise également un MappedByteBuffer mais ne persiste pas de données et est destiné à être utilisé comme un drop-in de remplacement de Socket / ServerSocket.
tour de latence pour un ping-pong de 1kB est d'environ une demi-microseconde.
MappedBus ( http://github.com/caplogic/mappedbus ) est une bibliothèque que j'ai ajoutée sur github qui permet la CIB entre plusieurs (plus de deux) processus Java/JVM par passage de message.
le transport peut être soit un fichier cartographié en mémoire, soit une mémoire partagée. Pour l'utiliser avec une mémoire partagée, suivez simplement les exemples sur la page github, mais pointez les lecteurs/rédacteurs vers un fichier sous "/dev/shm/".
c'est open source et le la mise en œuvre est expliquée sur la page github.
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 est construit sur le modèle de mémoire matérielle). Voir est-ce que plusieurs threads peuvent voir écrit sur un ByteBuffer directement mappé en Java? pour un tout à fait discussion utile sur le sujet.