La Mémoire partagée entre deux machines virtuelles
Est-il un moyen en JAVA, pour les deux machines virtuelles (en cours d'exécution sur la même machine physique), à utiliser/partager la même mermory espace d'adressage? Supposons qu'un producteur dans JVM1 met des messages à un pré-définis emplacement de mémoire, peut le consommateur sur JVM2 retrive le msg si elle connaît l'emplacement de la mémoire à regarder?
- Pas de. Vous ne pouvez pas accéder à l'arbitraire de la mémoire en Java. Mais, vous pouvez partager la mémoire entre deux machines virtuelles. Utiliser JNI et pisc. Ou des prises au cours de bouclage.
- Autant que je sache, il n'y a rien construit dans l'API de base. Vous pouvez utiliser
Socket
s à communiquer entre eux ou même par l'intermédiaire d'un tiers - qui Jvm ou deux Jvm??? merci de corriger la question du titre.
- Non, même si c'était une JVM vous ne pouvez pas accéder à un pré-défini l'emplacement de la mémoire. Vous pouvez
share
de l'espace mémoire à l'aide d'un multi-tenanted JVM comme waratek - Vous pouvez penser de la sérialisation des objets dans un fichier et de le renvoyer de l'autre jvm
- Quel est votre but de faire. Si vous voulez partager des informations entre deux machines virtuelles , alors vous pouvez aller pour un RMI.
- Selon le cas d'utilisation, il peut être possible d'utiliser de la mémoire mappée IO pour obtenir quelque chose d'à peu près similaire à la mémoire partagée. Voir javacodegeeks.com/2013/05/power-of-java-memorymapped-file.html
- Pourquoi voulez-vous faire cela? Si c'est si la performance est critique qu'une socket Unix ne fonctionne pas, Java est probablement le mauvais choix.
Vous devez vous connecter pour publier un commentaire.
Solution 1:
La meilleure solution à mon avis est d'utiliser les fichiers mappés en mémoire. Cela vous permet de partager une région de la mémoire entre un nombre quelconque de processus, y compris d'autres non des programmes java. Vous ne pouvez pas placer des objets java dans un fichier mappé en mémoire, à moins que vous sérialiser eux. L'exemple suivant montre que vous pouvez établir la communication entre deux processus différents, mais vous devez le rendre beaucoup plus sophistiqués pour permettre une meilleure communication entre les processus. Je vous suggère de regarder à Java NIO paquet, plus précisément les classes et les méthodes utilisées dans les exemples ci-dessous.
Serveur:
Client:
Solution 2:
Une autre solution est d'utiliser Java Sockets à communiquer dans les deux sens entre les processus. Cela a l'avantage supplémentaire de permettre la communication sur un réseau très facilement. On pourrait faire valoir que c'est plus lent que d'utiliser les fichiers mappés en mémoire, mais je n'ai pas de critères de référence pour appuyer cette affirmation en place. Je ne poste pas de code pour la mise en œuvre de cette solution, car cela peut devenir très compliqué à mettre en place un réseau fiable protocole et est assez spécifique à l'application. Il ya beaucoup de bons sites de réseautage qui peut être trouvé avec la fonction de recherche rapide.
Maintenant les exemples ci-dessus sont, si vous voulez partager la mémoire entre deux processus différents. Si vous voulez juste pour lire/écrire à l'arbitraire de la mémoire dans le processus actuel, il y a quelques avertissements que vous devez savoir en premier. Cela va à l'encontre de l'ensemble de ce principe de la JVM et que vous vraiment ne devraient pas le faire dans le code de production. Vous ne respectez toutes les consignes de sécurité et peut très facilement crash de la JVM si vous n'êtes pas très prudent.
Cela étant dit, il est assez amusant d'expérimenter avec. Pour lire/écrire à l'arbitraire de la mémoire dans le processus actuel, vous pouvez utiliser le
sun.misc.Unsafe
classe. Il est présent sur toutes les machines virtuelles que je suis au courant et ont utilisé. Un exemple qui montre comment utiliser la classe peut être trouvé ici.Il y a quelques CIB bibliothèques qui facilitent l'utilisation de la mémoire partagée via des fichiers mappés en mémoire en Java.
Chronique-La File D'Attente
Chronique de la File d'attente est semblable à un non-bloquant Java
Queue
, sauf que vous pourriez offrir un message dans une JVM et sondage dans une autre JVM.Dans les deux machines virtuelles, vous devez créer un
ChronicleQueue
instance dans le même FS répertoire (placer ce répertoire dans un répertoire de la mémoire-monté FS si vous n'avez pas besoin de message persistance):Écrire un message dans une JVM:
Lire un message dans une autre JVM:
Aeron CIB
Aeron est plus que juste de l'IPC de la file d'attente (c'est un réseau de communication cadre), mais il fournit un IPC de la fonctionnalité ainsi. Il est similaire à la Chronique de File d'attente, une différence importante est qu'il utilise SBE bibliothèque de message marshalling/demarshalling, tandis que la Chronique de File d'attente La Chronique De Fil.
Chronique De La Carte
Chronique de la Carte permet la communication IPC certains des principaux. Dans les deux machines virtuelles, vous devez créer une carte avec des configurations identiques et ont persisté au même fichier (le fichier doit être localed dans la mémoire-monté FS si vous n'avez pas besoin de disque réel de la persistance, de l'e. g. dans
/dev/shm/
):Puis dans une JVM, vous pourriez écrire:
Sur le récepteur de la JVM:
Distributed_cache est la meilleure solution pour répondre à vos exigences.
Quelques options:
Terre cuite permet aux threads dans un cluster de machines virtuelles à interagir les uns avec les autres à travers la JVM des limites à l'aide de la même intégré dans la JVM des installations de l'extension d'un cluster à l'échelle de sens
Oracle_Coherence est propriétaire d'unUn Java-base de données en mémoire de la grille, conçu pour avoir une meilleure fiabilité, l'évolutivité et les performances que les traditionnels de bases de données relationnelles les systèmes de gestion de
Ehcache est largement utilisé open source Java cache distribué pour objectif général la mise en cache, Java EE et de la lumière-poids des conteneurs. Il dispose d'une mémoire et un disque de magasins, de reproduire par copie et de l'invalider, auditeurs, la mise en cache des chargeurs, des cache les extensions, le cache, les gestionnaires d'exception, un gzip la mise en cache filtre de servlet, de détente, et de l'Api SOAP
Redis est une structure de données du serveur. Il est open-source, en réseau, en mémoire, et stocke les clés avec en option la durabilité.
Couchbase_Server est un open-source, distribué (shared-nothing architecture) multi-modèle NoSQL orientée document logiciel de base de données qui est optimisé pour les applications interactives. Ces applications peuvent servir à plusieurs utilisateurs simultanés par la création, le stockage, la récupération, l'agrégation, la manipulation et la présentation des données.
Utile messages:
Qu'est-ce que la terre Cuite?
Est en terre Cuite d'un cache distribué?
infoq article
Honnêtement, vous ne voulez pas partager le même espace mémoire. Vous devez envoyer uniquement les données dont vous avez besoin à l'autre de la JVM. Cela étant dit, dans le cas où vous ne besoin de la mémoire partagée, d'autres solutions existent.
L'Envoi De Données
Deux machines virtuelles ne partagent pas la même mémoire les points d'accès, il est donc impossible d'utiliser une référence d'une JVM à utiliser dans un autre. Une nouvelle référence sera simplement à créer, car ils ne connaissent pas les uns les autres.
Cependant, vous pouvez expédier des données à l'autre de la JVM, et de retour dans une variété de façons:
1) à l'Aide de RMI, vous pouvez configurer un serveur distant pour analyser les données. Je l'ai trouvé un peu compliqué à mettre en place car elle nécessite des modifications de sécurité et que les données soient
Serializable
. Vous pouvez en savoir plus sur le lien.2) à l'Aide d'un serveur est la vieille méthode de l'envoi de données à différents endroits. Une façon de mettre en œuvre c'est à l'aide d'un
ServerSocket
et la connexion avec uneSocket
surlocalhost
. Les objets doivent encore êtreSerializable
si vous souhaitez utiliserObjectOutputStream
.Le Partage De Données
Ceci est très dangereux et instables, de bas niveau, et, ainsi, dangereux (littéralement).
Si vous souhaitez utiliser du code Java, vous pouvez prendre un coup d'oeil à l'aide de
s.m.Dangereux
, en utilisant les adresses de mémoire correctes, vous serez en mesure de récupérer les Objets stockés par la sauvegarde de C/C++ tableaux dans l'OS.Sinon, vous pouvez utiliser
native
méthodes pour accéder à la C/C++ tableaux vous-même, bien que je n'ai aucune idée de comment cela pourrait être mis en œuvre.Oui,
avec un programme intermédiaire, vous pouvez écrire et lire arbitraire emplacements de mémoire. Vous ne pouvez pas le faire uniquement en Java.
Par exemple, vous pouvez écrire un morceau de code C++ qui permet la lecture de l'arbitraire d'un emplacement de la mémoire et l'appeler via JNI. La même chose est vraie dans le sens inverse pour écrire à une adresse de mémoire.
Écrire une définition de la classe de première de la classe qui doit gérer cela, par exemple:
Puis vous le compilez. Ensuite, vous utilisez javah.exe (ou l'équivalent linux) pour générer un en-tête pour elle:
Maintenant vous écrivez un .fichier cpp qui comprend que l'en-tête et définit les méthodes. La compilation de la DLL. Pour charger le .dll, vous pouvez utiliser la -Djava.de la bibliothèque.chemin de la JVM paramètre avec la valeur appropriée, ou d'un Système.loadLibrary().
Note de prudence: je ne recommande pas de faire cela. Il y a certainement de meilleures façons de faire ce que vous voulez faire.
0x3f7e
n'est pas la même adresse physique pour tous les processus.0x3f7e
dans JVM1 n'est pas le même que les données à l'adresse0x3f7e
dans JVM2. De JVM2, si vous voulez lire des données à partir du tas de JVM1, vous devriez obtenir JVM1 PID, copiez son tas local (si vous obtenez la permission) et de lire les données que vous souhaitez, à une adresse qui serait probablement0x3f7e
mais peut-être pas. C'est ce que j'appelle le "piratage d'adresse" (0x3f7e
dans JVM1 vu de JVM2 peut être quelque chose de différent de0x3f7e
).processes
viapure java
? Si non, alors perdre de l'attitude.Jocket, un projet expérimental que j'ai faite il y a quelques années fait exactement cela.
Il comprend une baisse-dans le remplacement pour
java.net.Socket
etjava.net.ServerSocket
si vous souhaitez utiliserInput/OutputStream
.Pour chaque direction de canal utilise une paire de mémoires tampon circulaire de la poste et obtenir les données, l'une pour les "paquets" et une pour l'adresse de paquets). Les tampons sont obtenus grâce à un
RandomAccessFile
.Il comprend une petite JNI couche (linux) pour mettre en œuvre l'IPC de synchronisation (c'est à dire informer les autres processus de la disponibilité des données), mais ce n'est pas obligatoire si vous souhaitez vérifier les données.
Dangereux avec pivot hors de segment de mémoire
Que penser de l'utilisation Impropre à la copie de l'Objet d'octets à un chef de zone, puis quelques-comment passer un bon pointeur et le nom de la classe à la 2ème JVM qui va utiliser le pointeur et le nom de classe de copier et jeté hors de la mémoire pour un objet tas en 2ème de la JVM.
Ce n'est pas la même instance d'objet, mais une copie rapide, sans sérialisation.
alors maintenant, vous passez
MyStructure
etp
de ((MyStructure)p.pointeur).x à une 2ème JVM, et vous devriez être capable de:Je peux imaginer un cas d'utilisation: supposons que vous avez 2 Microservices qui peuvent ou peuvent ne pas être en cours d'exécution dans la même serveur et un client de stratégie, peut-être mis en œuvre dans le conteneur du serveur d'applications, qui sait où les services sont déployés, dans le cas où il détecte le service demandé est en local, il peut utiliser un Dangereux base de client de service à la requête de l'autre service de manière transparente. Méchant, mais intéressant, j'aimerais voir les implications sur les performances de la non-utilisation du réseau, en contournant WebAPI (en appelant directement la manipulation de la manette) et pas de la sérialisation. Outre les paramètres du contrôleur dans ce cas, le contrôleur lui-même doit être fournie. Ne pensez même pas à la Sécurité.
des extraits de code emprunté à https://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/