Каков наилучший способ доступа к памяти на Java, аналогичный mmap?
Я работаю над Java-приложением, которое должно взаимодействовать с приложением C. Приложение C использует разделяемую память и mmap для связи, и мне нужно, чтобы приложение Java имело доступ к той же самой памяти.
Моя первая попытка заключалась в использовании вызовов JNI для извлечения данных из общей памяти, но накладные расходы на каждый вызов JNI снизили производительность, поэтому я хотел бы получить доступ к этой памяти на Java и выполнить поиск данных на Java-сторона.
Идея, которую я имею, это то, что мне нужно будет сделать следующее:
- Используйте один вызов JNI, чтобы получить местоположение разделяемой памяти, которое мне нужно прикрепить к
- Создайте новый FileChannel()
- Используйте этот FileChannel для создания MappedByteBuffer, используя map()
Это лучший способ сделать это? Кроме того, я не уверен, как создать FileChannel, чтобы указать на правильную ячейку памяти.
Ответы
Ответ 1
Посмотрите на использование ByteBuffer.allocateDirect
. По-видимому, эти буферы могут быть переданы через слой JNI на собственный код, который может напрямую обращаться к памяти.
См. эту страницу (цитируется ниже) для подсказок.
Теперь код JNI не только обнаруживает адрес собственного пространства памяти внутри буфера, созданного с помощью ByteBuffer.allocateDirect() на стороне Java, но он может выделять свою собственную память (например, с помощью malloc()) а затем перезвоните в JVM, чтобы обернуть это пространство памяти в новый объект ByteBuffer (для этого метод JNI - это NewDirectByteBuffer()).
Ответ 2
Я бы написал небольшой модуль C mmaps совместно используемую память и используемые сокеты, чтобы другое приложение могло видеть эту память (например, ваше приложение Java)
Ответ 3
Если у вас есть приложение C и Java, они могут просто общаться через консольные потоки - уродливые для двоичных данных, но это возможно. Я бы обменялся разделяемой памятью на другой стиль передачи сообщений - например. Пара сокетов TCP/IP.
Btw, какие данные передаются и насколько они велики?
Ответ 4
Нельзя ли написать 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.
Ответ 5
Если вы могли бы сохранить данные в файл на C, а затем получить доступ к файлу с Java, это было бы лучше. AFAIK вы не можете указывать на память так, как хотите использовать Java.