Каков наилучший способ доступа к памяти в Java, похожий на mmap? - PullRequest
17 голосов
/ 14 июля 2009

Я работаю над приложением Java, которое должно взаимодействовать с приложением Си. Приложение C использует совместно используемую память и mmap для связи, и мне нужно, чтобы приложение Java имело доступ к той же памяти.

Моя первая попытка состояла в использовании вызовов JNI для извлечения данных из общей памяти, но издержки каждого вызова JNI снижали производительность, поэтому я хотел бы получить способ получить доступ к этой памяти в Java и выполнить поиск данных на Java сторона.

У меня есть идея, что мне нужно сделать следующее:

  1. Используйте один вызов JNI, чтобы получить местоположение общей памяти, к которой мне нужно присоединиться
  2. Создать новый FileChannel ()
  3. Используйте этот FileChannel для создания MappedByteBuffer с помощью map ()

Это лучший способ сделать это? Кроме того, я не уверен, как на самом деле создать FileChannel, чтобы он указывал на правильную ячейку памяти.

Ответы [ 5 ]

11 голосов
/ 14 июля 2009

Изучите использование ByteBuffer.allocateDirect. Очевидно, эти буферы могут передаваться через уровень JNI в собственный код, который может напрямую обращаться к памяти.

См. эту страницу (цитируется ниже) для подсказок.

Теперь код JNI может не только обнаружить адрес собственной области памяти внутри буфера, созданного с помощью ByteBuffer.allocateDirect () на стороне Java, но и выделить собственную память (например, с помощью malloc ()) и затем перезвоните JVM, чтобы обернуть это пространство памяти в новый объект ByteBuffer (метод JNI, чтобы сделать это, является NewDirectByteBuffer ()).

1 голос
/ 14 июля 2009

я бы написал небольшой модуль C, отображающий общую память и использующий сокеты, чтобы другое приложение могло видеть эту память (например, ваше приложение Java)

0 голосов
/ 14 июля 2009

Не могли бы вы написать класс Java с некоторыми нативными методами, написать реализацию нативного метода в C, чтобы делать то, что вы хотите с mmap. Затем скомпилируйте это в собственную библиотеку и добавьте ее в среду выполнения, используя LD_LIBRARY_PATH. Это позволит вам делать нативные C-вызовы в Java без издержек JNI (я думаю).

Некоторые уроки здесь: ссылка

Например, вы бы написали класс Java, такой как:

JMMap.java

public class JMMap {
    public native void write(...)
}

Затем запустите javah для файла классов, чтобы получить что-то вроде:

JMMap.h

JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject);

Реализуйте это в файле .c. Скомпилируйте это в библиотеку. Добавьте его в путь LD, а затем просто вызовите функцию Java.

0 голосов
/ 14 июля 2009

Если у вас есть приложение C и Java, они могут просто обмениваться данными через потоки консоли - безобразно для двоичных данных, но возможно. Я бы обменял общую память на более стиль передачи сообщений - например, Пара сокетов TCP / IP.

Кстати, какие данные передаются и насколько они велики?

0 голосов
/ 14 июля 2009

Если бы вы могли сохранить данные в файл на C, а затем получить доступ к файлу из Java, это было бы лучше всего. AFAIK, вы не можете указывать на память так, как вы хотели бы использовать Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...