query pasar objetos entre actividades java jni

pasar - query native java



¿Qué es una implementación nativa en Java? (5)

Los métodos nativos en Java se implementan usando la '' Interfaz nativa de Java '', conocida como JNI.

Esta pregunta ya tiene una respuesta aquí:

Si miramos la clase de objetos de Java, podemos encontrar algunos de los métodos, como:

public native int hashCode() protected native Object clone()

¿Qué son estos nativos y cómo funcionan estos métodos?


La mayoría de los métodos nativos se implementan utilizando JNI como se menciona en otras respuestas.

Sin embargo, los métodos críticos de rendimiento como Object.hashCode se implementan típicamente como intrínsecos. Cuando el código de bytes se compila en código máquina, el compilador de Java reconoce la llamada al método e ingresa el código apropiado directamente. Obviamente, esto va a ser mucho más rápido que pasar por JNI por un método trivial.

Muchas personas Object.hashCode que Object.hashCode devolverá la dirección de la representación del objeto en la memoria. En las implementaciones modernas, los objetos se mueven dentro de la memoria. En cambio, se usa un área del encabezado del objeto para almacenar el valor, que puede derivarse de forma perezosa de la dirección de la memoria en el momento en que se solicita el valor por primera vez.


Los métodos nativos se implementan principalmente en C y se compilan en código nativo que se ejecuta directamente en la máquina. Esto está en contraste con los métodos normales, que se implementan en Java y se compilan en el código de bytes de Java, que es ejecutado por la Máquina Virtual de Java (JVM).

Para interactuar con estos métodos desde Java, necesita usar la Interfaz nativa de Java (JNI) .

El código nativo es principalmente necesario para acceder a cosas de bajo nivel. En el caso de hashCode, esta es la dirección del objeto en la memoria. Mi conjetura para la copia es que copia la memoria cruda de un objeto dado a la clonada. Otros usos del código nativo son para acceder a las características o el hardware del sistema operativo.

El inconveniente de utilizar código nativo es que usted pierde la seguridad y protección de la JVM, es decir, su programa puede fallar o tener agujeros de seguridad debido a errores en el código nativo.


Estos métodos son intrínsecos o están escritos fuera de Java en código "nativo", es decir, específicos de la máquina.

Los que mencionas son intrínsecos y forman parte del JDK, pero también puedes escribir métodos nativos usando la interfaz nativa de Java (JNI). Esto normalmente usaría C para escribir los métodos, pero muchos otros lenguajes, como python, le permiten escribir métodos de esta manera con bastante facilidad. El código está escrito de esta manera, ya sea para el rendimiento, o porque necesita acceder a la infraestructura específica de la plataforma que no se puede hacer en Java simple.

En el caso de hashcode() , esto es implementado por la JVM. Esto se debe a que a menudo el código hash se relacionará con algo que solo la JVM conoce. En las primeras JVM esto estaba relacionado con la ubicación del objeto en la memoria: en otras JVM, el objeto puede moverse en la memoria, por lo que se puede usar un esquema más complicado (pero aún muy rápido).


¿Qué son estos nativos y cómo funcionan estos métodos?

Ejemplo mínimo para aclarar las cosas:

Main.java :

public class Main { public native int square(int i); public static void main(String[] args) { System.loadLibrary("Main"); System.out.println(new Main().square(2)); } }

Main.c :

#include <jni.h> #include "Main.h" JNIEXPORT jint JNICALL Java_Main_square( JNIEnv *env, jobject obj, jint i) { return i * i; }

Compilar y ejecutar :

sudo apt-get install build-essential openjdk-7-jdk export JAVA_HOME=''/usr/lib/jvm/java-7-openjdk-amd64'' javac Main.java javah -jni Main gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include / -I${JAVA_HOME}/include/linux Main.c java -Djava.library.path=. Main

Salida :

4

Probado en Ubuntu 14.04. También trabajé con Oracle JDK 1.8.0_45.

Ejemplo en GitHub para que juegues.

Interpretación :

Te permite:

  • llamar a una biblioteca cargada dinámicamente compilada (aquí escrita en C) con código de ensamblaje arbitrario de Java
  • y obtener resultados de nuevo en Java

Esto podría ser utilizado para:

  • escriba un código más rápido en una sección crítica con mejores instrucciones de ensamblaje de la CPU (no portátil)
  • hacer llamadas directas al sistema (no es portátil)

con la compensación de una menor portabilidad.

También es posible llamar a Java desde C, pero primero debe crear una JVM en C: ¿Cómo llamar a las funciones de Java desde C ++?

Ejemplo en OpenJDK 8

Busquemos encontrar dónde se define Object#clone en jdk8u60-b27.

Primero encontramos:

find . -name Object.java

lo que nos lleva a jdk / src / share / classes / java / lang / Object.java # l212 :

protected native Object clone() throws CloneNotSupportedException;

Ahora viene la parte difícil, encontrar dónde está el clon en medio de toda la indirección. La consulta que me ayudó fue:

find . -iname object.c

que encontraría archivos C o C ++ que podrían implementar los métodos nativos de Object. Nos lleva a jdk / share / native / java / lang / Object.c # l47 :

static JNINativeMethod methods[] = { ... {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone}, }; JNIEXPORT void JNICALL Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls) { (*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])); }

que nos lleva al símbolo JVM_Clone :

grep -R JVM_Clone

lo que nos lleva a hotspot / src / share / vm / prims / jvm.cpp # l580 :

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle)) JVMWrapper("JVM_Clone");

Después de expandir un montón de macros, llegamos a la conclusión de que este es el punto de definición.