Ich verstehe, dass mit GetDoubleArrayElements die JVM entscheidet, ob die Elemente von Array kopiert werden sollen oder nicht. Gibt es in diesem Fall eine Möglichkeit, die Kopie zu vermeiden? Wenn nicht, gibt es eine andere Möglichkeit, von Java auf C ohne Kopieren zu übertragen? Ich übergebe sehr große Arrays, und ich wünschte, ich könnte die Kopie vermeiden. Danke
Der JNI-Leitfaden lautet:
In JDK / JRE 1.1 können Programmierer Get / ReleaseArrayElements-Funktionen verwenden, um einen Zeiger auf primitive Array-Elemente zu erhalten. Wenn die VM das Pinning unterstützt, wird der Zeiger auf die ursprünglichen Daten zurückgegeben ; Andernfalls wird eine Kopie erstellt.
Neue Funktionen, die in JDK / JRE 1.3 eingeführt wurden, ermöglichen es nativem Code, einen direkten Zeiger auf Array-Elemente zu erhalten, selbst wenn die VM das Pinning nicht unterstützt.
Diese "neuen Funktionen" sind GetPrimitiveArrayCritical
und ReleasePrimitiveArrayCritical
, die die Garbage Collection komplett deaktivieren und daher mit Vorsicht verwendet werden müssen. Zusammengefasst handelt es sich also um ein VM-Problem und nicht um ein API-Problem. Vergessen Sie nicht, dass sich der Garbage Collector ohne Pinning dazu entschließen könnte, den Heap zu komprimieren und Ihr Array physisch zu verschieben, so dass der direkte Pointer doch wenig Nutzen hätte.
Wie Peter vorgeschlagen hat, könnten Sie mit einem java.nio.DoubleBuffer
arbeiten, anstatt Arrays zu verwenden. Die JNI-Funktion
ermöglicht Ihnen den Zugriff darauf.