Я создаю огромный график в JVM (Scala), который я хочу использовать повторно, настраивая алгоритмы. Я бы предпочел не перезагружать его каждый раз с диска. Есть ли способ заставить его сидеть в одной JVM при подключении от другого, где разрабатываются алгоритмы?
Как я могу обмениваться памятью между двумя экземплярами JVM?
Ответ 1
Сохраните свой график на диске, а затем переместите его в память с помощью MappedByteBuffer. Оба процесса должны использовать одну и ту же память, которая будет использоваться в кэше страниц.
Ответ 2
Два JVM звучат сложнее, чем нужно. Считаете ли вы, что вы делаете какую-то "горячую установку", где ваша основная программа загружает график, отображает пользовательский интерфейс и затем запрашивает (или автоматически ищет) файл jar/class для загрузки, содержащий ваш фактический код алгоритма? Таким образом, ваш код алгоритма будет работать в том же jvm, что и ваш график, но вам не придется перезагружать график, чтобы перезагрузить новую реализацию алгоритма.
ОБНОВЛЕНИЕ для адресации вопроса OP в комментарии:
Здесь вы можете структурировать свой код, чтобы ваши алгоритмы были заменяемыми. Не имеет значения, что делают различные алгоритмы, если они работают с одними и теми же входными данными. Просто определите интерфейс, как показано ниже, и выполните его алгоритмы графа.
public interface GraphAlgorithm {
public void doStuff(Map<whatever> myBigGraph)
}
Если ваши алгоритмы отображают результаты для какого-то виджета, вы можете передать это тоже, или doTuff() возвращает какой-то объект результатов.
Ответ 3
Вы рассматривали платформу OSGi? Он живет в одном JVM, но позволит вам обновлять пакеты с помощью алгоритмов без перезагрузки платформы. Таким образом, у вас может быть долгосрочный запущенный пакет с вашими огромными структурами данных и кратковременными пакетами алгоритмов, которые получают доступ к данным.
Ответ 4
Возможно, с помощью RMI? Есть ли один экземпляр, работающий как сервер, а остальные как клиенты?
Я думаю, что это будет намного сложнее перезагрузки с диска.
Ответ 5
Вы можете создать на нем интерфейс и выставить его через (скажем) RMI.
Мои первоначальные мысли по чтению вашего сообщения, однако,
- насколько большой этот график?
- можно ли оптимизировать свою процедуру загрузки?
Я знаю, что LinkedIn имеет обширный график людей и подключений, который постоянно хранится в памяти и занимает несколько часов, чтобы перезагрузить. Но я считаю, что это действительно исключительный случай.
Ответ 6
Если стоит построить график, возможно, вы можете сериализовать объект.
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
Затем вы можете создать свой объект из файла
ByteArrayInputStream inputBuffer = new ByteArrayInputStream(b);
ObjectInputStream inputStream = new ObjectInputStream(inputBuffer);
try {
Graph graph = (Graph) inputStream.readObject();
} finally {
if (inputStream != null) {
inputStream.close();
}
}
Просто замените ByteArrayInputStream на FileInputStream
Ответ 7
Если проблема заключается только в том, чтобы динамически загружать и запускать ваш код без столкновений имен, может быть достаточно пользовательского загрузчика классов. для нового запуска просто кэшируйте все файлы классов в новом загрузчике классов.
Ответ 8
Рассматривали ли вы просто меньшее количество выборочных данных для тестирования ваших алгоритмов?
Ответ 9
Terracotta разделяет память между многими экземплярами JVM, поэтому вы можете легко применить кластер к своей системе.
Ответ 10
Woo! поздно на вечеринку.
Если на локальной машине, похожей на отображенные байт-буферы, есть прямая память apache. http://directmemory.apache.org/
Если вы хотите, чтобы он был распространен, попробуйте http://hazelcast.org/. Его используют многие крупные проекты. Конечно, ваши объекты должны быть сериализуемыми.