2011-12-20 8 views
11

è fattibile per collegare un filo nativo in modo permanente alla JVM (AttachCurrentThread) (o) è meglio attaccare quando mai necessario (si chiamano le funzioni java) e staccare immediatamente una volta che il lavoro è fattoQuali sono le conseguenze se proviamo ad associare permanentemente un thread nativo al DVM (JVM)?

ho scritto un nativo del campione app con i casi di cui sopra, non ha trovato alcuna differenza. Ma su google mi sono reso conto vagamente che, quando collegato a JVM, la schedulazione dei thread della JVM è responsabile della programmazione del sistema operativo altrimenti programmerà il thread nativo (se non è collegato). È vero?

È importante staccare qualsiasi filo precedentemente collegato; in caso contrario, il programma non uscirà quando si chiama DestroyJavaVM. - http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniref.html#attach

Ci saranno problemi di prestazioni?
Per favore fatemi sapere se qualcuno lo sa, è il mio aspetto importante del design.

Grazie & Cordiali saluti.

+0

può fornire informazioni sul motivo per cui si desidera collegare a un thread nativo? – Michael

+0

Stiamo sviluppando alcune applicazioni in cui solitamente viene chiamato il codice Java una volta ogni tanto. A un certo punto del tempo nativo chiamerà il codice Java rigorosamente, quindi ogni volta che si collega e si scollega il thread sta ostacolando le prestazioni dell'applicazione (in quanto non è un ciclo di chiamate di funzioni Java che non posso evitare di collegare e scollegare). Questa è la ragione per cui sto lavorando per i pro e contro del suddetto articolo. – Suman

+0

http://groups.google.it/group/android-ndk/browse_thread/thread/6aaf28efb838a9eb/5e66ad0af35c15c3 – Suman

risposta

4

In generale, il costo principale delle prestazioni è la creazione di thread a livello di sistema operativo. Il thread sta creando in modo nativo e quindi collegato o creato direttamente come java.lang.Thread dall'API Java.

Se si riutilizza lo stesso thread nativo, le prestazioni saranno buone. A proposito, non creare dozzine di thread nativi.

JVM does not schedule threads itself. Potrebbe costringerli in stato di sospensione per vari motivi, come la garbage collection. In questo caso specifico, deve attendere una chiamata JNI da un thread nativo prima di essere raccolta. Quindi è necessario evitare l'esecuzione di codice troppo lunga senza chiamata JNI per mantenere basso il consumo dell'ammontare della VM.

Inoltre, è necessario fare attenzione a chiamare DeleteLocalRef prima di scollegare un thread nativo altrimenti la VM perde memoria.

+0

Ci sono voluti tanti minuti per capire come sono alle prime armi con JAVA e Android – Suman

1

Quando un thread nativo è collegato in modo permanente, non è in grado di uscire dal thread nativo. Si blocca quando proviamo ad uscire dal thread nativo senza distaccarlo. Ma quando ci siamo staccati, il thread nativo è stato in grado di eseguire un'uscita aggraziata.

0

Non ho riscontrato alcuna conseguenza ad eccezione delle prestazioni potenziate.

Questo è esattamente ciò che faccio in un'applicazione che mischia i dati ByteBuffer allocati direttamente tra i due livelli. Ho scoperto che il costo di attaccamento/distacco costante era molto alto, come ci si potrebbe aspettare. Il mio approccio è quello di lanciare un singolo thread gestito da Java che fa una chiamata JNI bloccante all'avvio, che nel livello C/C++ contiene un ciclo di condizione/segnale (in modo da non mangiare i cicli della CPU). Posso quindi segnalare fino al ciclo ogni volta che i dati sono pronti per l'elaborazione, e viceversa posso segnalare fino a Java quando il duro lavoro è fatto.

new Thread(() -> myBlockingJNICall()).start(); 

Poi giù nello strato C:

#ifdef __cplusplus 
extern "C" 
{ 
#endif // __cplusplus 

    static JavaVM *jvm = nullptr; // captures the JVM on load 

    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *the_jvm, void* /*reserved*/) 
    { 
     jvm = the_jvm; 
     return JNI_VERSION_1_2; // must export 1_2 to use any of the new functions, 1_1 otherwise 
    } 

    JNIEXPORT jboolean JNICALL Java_myBlockingJNICall(JNIEnv *env, jobject) 
    { 
     // loop forever waiting for work and using env for signalling 
     // jvm is stored in case we need to manually attach (or perform more complex work requiring jvm access) 
     return JNI_TRUE; 
    } 

#ifdef __cplusplus 
} 
#endif // __cplusplus 
Problemi correlati