Come posso condividere la memoria tra due istanze JVM?

Costruisco un enorme grafico in JVM (Scala) che voglio usare ripetutamente, algoritmi di tweaking. Preferirei non ricaricarlo ogni volta dal disco. C’è un modo per farlo sedere in una JVM durante la connessione da un’altra, dove vengono sviluppati gli algoritmi?

Salva il tuo grafico su disco, quindi mappalo in memoria con MappedByteBuffer . Entrambi i processi dovrebbero utilizzare la stessa memoria, che verrà condivisa con la cache della pagina.

Due JVM sembrano più complicate di quanto debbano essere. Hai preso in considerazione l’idea di eseguire una sorta di installazione “hot deploy”, in cui il programma principale carica il grafico, visualizza l’interfaccia utente e poi chiede (o cerca automaticamente) un file jar / class da caricare contenente il codice dell’algoritmo corrente? In questo modo il codice dell’algoritmo sarebbe in esecuzione nella stessa jvm del tuo grafico, ma non dovresti ricaricare il grafico solo per ricaricare una nuova implementazione dell’algoritmo.

UPDATE per rispondere alla domanda dell’OP nel commento:

Ecco come puoi strutturare il tuo codice in modo che i tuoi algoritmi siano scambiabili. Non importa ciò che fanno i vari algoritmi, fintanto che operano sugli stessi dati di input. Basta definire un’interfaccia simile alla seguente e farla implementare dagli algoritmi del tuo grafico.

public interface GraphAlgorithm { public void doStuff(Map myBigGraph) } 

Se i tuoi algoritmi stanno visualizzando i risultati su un qualche tipo di widget, puoi passarlo anche tu, oppure doStuff () restituire qualche tipo di object risultati.

Hai preso in considerazione la piattaforma OSGi? Vive in una singola JVM, ma ti permetterà di aggiornare i bundle con algoritmi senza il riavvio della piattaforma. Pertanto, è ansible disporre di un pacchetto a lungo termine con le enormi strutture di dati e i bundle di algoritmi a breve termine che accedono ai dati.

Usando RMI forse? Hai un’istanza che lavora come server e il resto come client?

Penso che sarebbe molto più complicato del ricaricamento dal disco.

Puoi certamente creare un’interfaccia su di essa ed esporla tramite (diciamo) RMI .

Le mie prime riflessioni sulla lettura del tuo post, comunque, lo sono

  1. quanto è grande questo grafico?
  2. è ansible ottimizzare la procedura di caricamento?

So che LinkedIn ha un vasto grafico di persone e connessioni che viene tenuto in memoria in ogni momento e che impiega diverse ore per ricaricare. Ma immagino che sia un caso davvero eccezionale.

se il problema è solo quello di caricare ed eseguire dynamicmente il tuo codice senza conflitti di nomi, un programma di caricamento classi personalizzato potrebbe essere sufficiente. per una nuova esecuzione è sufficiente memorizzare nella cache tutti i file di class in un nuovo classloader.

Hai considerato semplicemente l’utilizzo di una piccola quantità di dati di esempio per testare i tuoi algoritmi?

Se è costoso build il tuo grafico, magari puoi serializzare l’object.

 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(graph); out.flush(); byte b[] = bos.toByteArray(); //you can use FileOutputStream instead of a ByteArrayOutputStream 

Quindi puoi build il tuo object dal file

 ByteArrayInputStream inputBuffer = new ByteArrayInputStream(b); ObjectInputStream inputStream = new ObjectInputStream(inputBuffer); try { Graph graph = (Graph) inputStream.readObject(); } finally { if (inputStream != null) { inputStream.close(); } } 

Basta sostituire ByteArrayInputStream con FileInputStream

Terracotta condivide la memoria tra molte istanze JVM in modo da poter applicare facilmente il cluster al sistema.

Corteggiare! in ritardo alla festa.

Se si trova su una macchina locale, simile ai buffer di byte mappati, esiste una memoria diretta di apache. http://directmemory.apache.org/

Se vuoi che sia distribuito, prova http://hazelcast.org/ . È utilizzato da molti grandi progetti. Ovviamente, i tuoi oggetti devono essere serializzabili.