2011-03-08 12 views
8

Entiendo que al usar GetDoubleArrayElements, es la JVM quien decide si copiar o no los elementos de Array. En este caso, ¿hay alguna forma de evitar la copia? Si no, ¿hay alguna otra forma de transferir de Java a C sin copiar? Estoy pasando Arrays muy grandes, y me gustaría poder evitar la copia. Gracias ¿Hay alguna forma de pasar una Java Array a C a través de JNI sin hacer una copia?

+2

Puede usar un DoubleBuffer para envolver un búfer de byte directo. Esto actualiza un área de memoria que se puede usar en Java/C directamente. –

Respuesta

4

El JNI guide dice:

En el JDK/JRE 1.1, los programadores pueden utilizar funciones get/ReleaseArrayElements para obtener un puntero a elementos de la matriz primitivos. Si la VM admite la fijación, el puntero a los datos originales se devuelve; de lo contrario, se hace una copia.

Las nuevas funciones introducidas en JDK/JRE 1.3 permiten que el código nativo obtenga un puntero directo a los elementos de la matriz, incluso si la VM no admite la fijación.

Estas "nuevas funciones" son GetPrimitiveArrayCritical y ReleasePrimitiveArrayCritical la que desactivar por completo la recolección de basura y tienen por lo tanto para ser utilizado con cuidado. En resumen, es un problema de VM en lugar de un problema de API. No olvide que sin fijar el recolector de basura puede decidir compactar el montón y mover físicamente su matriz, por lo que el puntero directo sería de poca utilidad después de todo.

Como Peter sugirió que podría trabajar con un java.nio.DoubleBuffer en lugar de utilizar matrices. La función JNI

void* GetDirectBufferAddress(JNIEnv* env, jobject buf); 

le permite acceder a ella.

+0

Me pregunto qué es lo preferido, byte [] con 'GetPrimitiveArrayCritical' o ByteBuffer con' GetDirectBufferAddress'? – Trilarion

+1

Eso realmente depende de su caso de uso. Una consideración podría ser usar 'GetPrimitiveArrayCritical' o' GetArrayElements' cuando sus datos son una salida de su código Java y una entrada de su código C. Debería usar 'GetDirectBufferAddress' cuando sus datos fluyan de otra manera. – Tilo

Cuestiones relacionadas