Я понимаю, что при использовании GetDoubleArrayElements именно JVM решает, копировать ли элементы массива. В этом случае есть ли способ избежать копирования? Если нет, есть ли другой способ перейти с Java на C без копирования? Я передаю очень большие массивы, и мне хотелось бы избежать копирования. Спасибо
Есть ли способ передать массив Java на C через JNI, не делая его копии?
Ответы (1)
В руководстве JNI говорится:
В JDK / JRE 1.1 программисты могут использовать функции Get / ReleaseArrayElements для получения указателя на примитивные элементы массива. Если виртуальная машина поддерживает закрепление, возвращается указатель на исходные данные; в противном случае делается копия.
Новые функции, представленные в JDK / JRE 1.3, позволяют машинному коду получать прямой указатель на элементы массива, даже если виртуальная машина не поддерживает закрепление.
Этими «новыми функциями» являются GetPrimitiveArrayCritical
и ReleasePrimitiveArrayCritical
, которые полностью отключают сборку мусора и поэтому должны использоваться с осторожностью. Таким образом, это проблема виртуальной машины, а не API. Не забывайте, что без закрепления сборщик мусора может решить сжать кучу и физически переместить ваш массив, поэтому прямой указатель в конце концов будет бесполезен.
Как сказал Питер, вы можете работать с java.nio.DoubleBuffer
вместо использования массивов. Функция JNI
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
позволяет получить к нему доступ.
GetPrimitiveArrayCritical
или ByteBuffer с GetDirectBufferAddress
?
- person Trilarion; 24.01.2018
GetPrimitiveArrayCritical
или GetArrayElements
, когда ваши данные являются выходными данными вашего кода Java и входными данными вашего кода C. Вы бы использовали GetDirectBufferAddress
, когда ваши данные текут в обратном направлении.
- person Tilo; 24.01.2018