Любая концепция разделяемой памяти в Java
AFAIK, память в Java основана на куче, из которой память распределяется по объектам динамически и нет понятия общей памяти.
Если понятия общей памяти нет, тогда связь между программами Java должна занимать много времени. В C, где межпроцессная связь быстрее осуществляется через общую память по сравнению с другими режимами связи.
Исправьте меня, если я ошибаюсь. Также, что самый быстрый способ для двух Java-прогов говорить друг с другом.
Ответы
Ответ 1
Поскольку для создания сегмента разделяемой памяти нет официального API, вам необходимо обратиться к вспомогательной библиотеке /DDL и JNI для использования разделяемой памяти, чтобы два процесса Java разговаривали друг с другом.
На практике это редко бывает проблемой, поскольку Java поддерживает потоки, поэтому на одной виртуальной машине Java можно запускать две "программы". Те будут разделять одну и ту же кучу, поэтому общение будет мгновенным. Кроме того, вы не можете получить ошибки из-за проблем с сегментом разделяемой памяти.
Ответ 2
Есть как минимум 2 способа сделать это - RAM Drive или Apache APR.
Подробнее здесь и здесь с некоторыми измерениями производительности.
Ответ 3
Peter Lawrey Проект Java Chronicle стоит посмотреть.
Это некоторые тесты, которые я сделал некоторое время назад, сравнивая различные варианты кучи и по-куче.
Ответ 4
Общая память иногда быстрая. Иногда его нет - он вредит кэшам процессора, а синхронизация часто является болью (и если она полагается на мьютексы и т.д., Это может быть серьезным снижением производительности).
Barrelfish - это операционная система, которая демонстрирует, что IPC, использующий передачу сообщений, фактически быстрее, чем разделяемая память, по мере увеличения количества ядер (на обычные архитектуры X86, а также более экзотические материалы NUMA NUCA, которые, как вы предполагали, были нацелены).
Итак, ваше предположение, что разделяемая память быстро требует тестирования для вашего конкретного сценария и вашего целевого оборудования. Это не всеобщее звуковое предположение в наши дни!
Ответ 5
Можно посмотреть на файлы с отображением памяти, используя Java NIO FileChannel или аналогичный (см. Метод map()). Мы использовали это очень успешно для связи (в нашем случае односторонней) между процессом Java и родным C на одном компьютере.
Я признаю, что я не эксперт в области файловой системы (к счастью, у нас есть один в штате!), но производительность для нас абсолютно невероятно быстрая - эффективно вы обрабатываете раздел кеша страницы как файл и читаете + запись на него напрямую без накладных расходов на системные вызовы. Я не уверен в гарантиях и согласованности - в Java есть методы, которые заставляют записывать изменения в файл, что означает, что они (иногда обычно "обычно" обычно "не уверены" ) записываются в фактический базовый файл (несколько "очень" чрезвычайно?) лениво, что означает, что некоторая доля времени в основном это просто сегмент разделяемой памяти.
В теории, как я понимаю, файлы с отображением памяти CAN действительно поддерживаются сегментом разделяемой памяти (они, по-моему, являются файловыми дескрипторами), но я не знаю, как это сделать на Java без JNI.
Ответ 6
Есть несколько сопоставимых технологий, о которых я могу думать:
- Несколько лет назад появилась технология под названием JavaSpaces, но это никогда не казалось захватывающим, позор, если вы спросите меня.
- В настоящее время существуют технологии распределенного кеша, такие как Coherence и Tangosol.
К сожалению, ни одна из них не будет иметь правильную скорость разделяемой памяти, но они имеют дело с проблемами одновременного доступа и т.д.
Ответ 7
Самый простой способ сделать это - создать два процесса для создания одного и того же файла с отображением памяти. На практике они будут использовать одно и то же пространство памяти без кучи. Вы можете захватить физический адрес этой памяти и использовать sun.misc.Unsafe
для записи/чтения примитивов. Он поддерживает concurrency с помощью методов putXXXVolatile/getXXXVolatile. Посмотрите CoralQueue, который предлагает IPC легко, а также межпоточную связь внутри одной JVM.
Отказ от ответственности. Я являюсь одним из разработчиков CoralQueue.
Ответ 8
Подобно Питеру Лоури, Java Chronicle, вы можете попробовать Jocket.
Он также использует MappedByteBuffer, но не сохраняет данные и предназначен для замены в Socket/ServerSocket.
Задержка латентности для пинг-понга размером 1 кБ составляет около полумикросекунды.
Ответ 9
MappedBus (http://github.com/caplogic/mappedbus) - это библиотека, которую я добавил в github, которые позволяют IPC между несколькими (более чем двумя) процессами Java/JVM посредством передачи сообщений.
Транспортировка может быть либо файлом с отображением памяти, либо разделяемой памятью. Чтобы использовать его с общей памятью, просто следуйте примерам на странице github, но укажите читателей/писателей в файл в разделе "/dev/shm/".
С открытым исходным кодом и реализация полностью объясняется на странице github.
Ответ 10
Информация, предоставленная Коуэном, верна. Однако даже разделяемая память не всегда будет одинаковой в нескольких потоках (и/или процессах) одновременно. Ключевой причиной является модель памяти Java (которая построена на модели аппаратной памяти). См. Можно ли несколько потоков видеть записи в прямом сопоставленном ByteBuffer в Java? для довольно полезного обсуждения темы.