Подтвердить что ты не робот

Любая концепция разделяемой памяти в Java

AFAIK, память в Java основана на куче, из которой память распределяется по объектам динамически и нет понятия общей памяти.

Если понятия общей памяти нет, тогда связь между программами Java должна занимать много времени. В C, где межпроцессная связь быстрее осуществляется через общую память по сравнению с другими режимами связи.

Исправьте меня, если я ошибаюсь. Также, что самый быстрый способ для двух Java-прогов говорить друг с другом.

4b9b3361

Ответ 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? для довольно полезного обсуждения темы.