IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

JNI et mémoire: Release<type>ArrayElements


Sujet :

Entrée/Sortie Java

  1. #1
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut JNI et mémoire: Release<type>ArrayElements
    Bonjour,

    j'ai une question sur l'utilisation de Release<type>ArrayElements. Je sais qu'il faut l'appeler afin de faire un "commit" des modifications faites sur un tableau.
    Mais j'ai dans certaines discussions (pas sur toutes), qu'il fallait toujours l'appeler, même si un tableau n'avait pas été modifié.

    Dans ce petit code, j'aurai tendance à ne l'appeler que pour le tableau de double, car il est modifié. Je ne l'appellerai pas pour le tableau d'int, car ce n'est qu'un pointeur local qui devrait donc être supprimé à la sortie de la fonction.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    JNIEXPORT jobject JNICALL Java_measures_miniball_Miniball_Compute2D (JNIEnv *env, jobject obj, jintArray Xarray, jdoubleArray Infos)
    	{
    	int length = env->GetArrayLength(Xarray) ;
    	int* X = env->GetIntArrayElements(Xarray, 0) ; // On récupère un pointeur sur le tableau.
     
    	double* infos = env->GetDoubleArrayElements(Infos, 0) ; // On récupère un pointeur sur le tableau.
    	// Je ne modifie que le tableau de double
    	infos[0] = 0.0 ;
    	infos[1] = 1.0 ;
    	env->ReleaseDoubleArrayElements(Infos, infos, 0) ; // Le commit...
    	return NULL ;
    	}

    Ai je raison ? (Ca m'ennuierait d'avoir des fuites mémoire :p)
    Merci par avance.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    D'après ce que je lit de la doc, je dirais que tu devrais l'appeler systématiquement. On y dit que le get peut retourner une copie du contenu du tableau. Même si tu ne modifie pas, sans signaler à la jvm que tu as fini, comment ces données peuvent être liberees.

  3. #3
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    D'après ce que je lit de la doc, je dirais que tu devrais l'appeler systématiquement.
    Merci.

    Citation Envoyé par tchize_ Voir le message
    On y dit que le get peut retourner une copie du contenu du tableau.
    Voilà le genre d'imprécision qui fait peur !!!
    Je m'attendais à avoir quelque chose de fixe copie ou pointeur, mais pas un ou peut être l'autre !!!
    D'autant plus que la copie fait perdre du temps.
    Cela peut me poser de gros soucis, car je travaille sur des images (potentiellement grandes). Avoir un pointeur serait parfait, une recopie de mon image serait alors catastrophique au niveau performances.

    Et je suppose qu'il n'y a aucun moyen pour savoir de manière certaine si on a un pointeur ou une copie... ?

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    cf la doc:

    http://docs.oracle.com/javase/1.5.0/...s.html#wp17314

    NativeType *Get<PrimitiveType>ArrayElements(JNIEnv *env,
    ArrayType array, jboolean *isCopy);
    .....
    If isCopy is not NULL, then *isCopy is set to JNI_TRUE if a copy is made; or it is set to JNI_FALSE if no copy is made.
    isCopy contienra true ou false suivant que tu as obtenu une copie ou non.

    L'idée quand on accélère des codes avec du JNI, c'est de ne pas interagir au maximum avec java: ton image doit être dans la partie native. Seulement à la toute fin du traitement tu la transforme en un tableau java. Chaque fois que tu utilie un point JNI / java, tu es soumis à différentes containtes de la JVM qui peuvent impacter tes performances.

  5. #5
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Pourtant un peu plus loin on trouve :

    RETURNS:
    Returns a pointer to the array elements, or NULL if the operation fails.
    Mais encore plus loin on retrouve pour "Release<PrimitiveType>ArrayElements Routines"
    The elems argument is a pointer derived from array using the corresponding Get<PrimitiveType>ArrayElements() function. If necessary, this function copies back all changes made to elems to the original array.
    Bref... pas très clair.
    Par contre c'est la documentation pour Java 1.5 et il semblerait qu'elle n'ait plus évolué depuis. Plus d'évolution de JNI depuis ?

  6. #6
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    J'ai essayé de modifier mon code pour savoir si une copie est faite ou non:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	jboolean *j ;
    	int length = env->GetArrayLength(Xarray) ;
    	int* X = env->GetIntArrayElements(Xarray, j) ;
    	if ( *j == JNI_TRUE ) printf("Oops copy\n") ;
    	else printf("OK\n") ;
    Ca compile, mais j'ai une magnifique "fatal error".
    Par contre si je ne fais pas le "printf" (donc juste "if ( *j == JNI_TRUE ) ;") tout se passe correctement. Mais je peux quand même faire un printf dans mon code avant ou après sans erreur.
    Là... je suis totalement perdu !!!

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    je crois que si la méthode the demande un pointeur vers un jboolean, c'est qu'elle s'attends à pouvoir y écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	jboolean j ;
    	int length = env->GetArrayLength(Xarray) ;
    	int* X = env->GetIntArrayElements(Xarray, &j) ;
    	if ( j == JNI_TRUE ) printf("Oops copy\n") ;
    	else printf("OK\n") ;

  8. #8
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut

    Ca fait vraiment trop longtemps que je n'ai pas fait de C

    La méga super mauvaise nouvelle, c'es que Get<Type>ArrayElements retourne systématiquement JNI_TRUE. Donc j'ai toujours une copie et avec mes images je vais sérieusement perdre en performances.

  9. #9
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Est ce que par hasard le fait qu'une copie soit faite ou non dépendrait de l'OS ?

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    Ton array viens d'où? Je connais pas grand chose en jni. Je crois que ca dépend de si l'array a été assigné sur la stack, dans la heap ou viens du hardware (comme une volatile image) et des capacités de la jvm

  11. #11
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ton array viens d'où?
    De là :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    private native Disk Compute2D(final int[] X, final int[] Y, final double[] Info) ;
     
    public Disk Compute2D(final int[] X, final int[] Y)
    	{
    	final double[] infos = new double[2] ;
    	Disk disk = Compute2D(X, Y, infos) ;
    	Accuracy = infos[0] ;
    	Valid = infos[1] == 1.0 ;
    	return disk ;
    	}
     
    public Disk Compute2D(List<Coordinates> list)
    	{
    	int nb = 0 ;
    	final int[] X = new int[list.size()] ;
    	final int[] Y = new int[X.length] ;
     
    	Iterator<Coordinates> iter = list.iterator() ;
    	while ( iter.hasNext() )
    		{
    		Coordinates c = iter.next() ;
    		X[nb] = c.X ;
    		Y[nb] = c.Y ;
    		nb++ ;
    		c = null ;
    		}
    	iter = null ;
     
    	Disk disk = Compute2D(X, Y) ;
     
    	return disk ;
    	}
    J'ai une liste de coordonnées que je transforme en deux tableaux, que je passe ensuite à mon code natif.


    Citation Envoyé par tchize_ Voir le message
    Je crois que ca dépend de si l'array a été assigné sur la stack, dans la heap ou viens du hardware (comme une volatile image) et des capacités de la jvm
    Peut on influencer quelque chose afin de subtilement forcer un pointer plutôt qu'une copie ?

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    J'en sais rien. Ce que je ferais moi c'est transférer définitivement certaines données vers la partie native et y faire tout les calculs.

  13. #13
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    transférer définitivement certaines données vers la partie native et y faire tout les calculs.
    Mais du coup alors plus du tout de java :-)
    Il me faudrait alors transcrire la totalité de mon code java en C++.

  14. #14
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    La solution est d'utiliser GetPrimitiveArrayCritical.
    Cette méthode permet de forcer au maximum pour avoir un pointeur, mais elle a certaines restrictions.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JNI] allocation mémoire du node natif
    Par Ange_blond dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 31/08/2010, 18h09
  2. [JNI]Fuite mémoire/ core dumped JVM
    Par kinder29 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 02/09/2008, 16h31
  3. Occupation en mémoire suivant le type de la variable.
    Par nodogeid dans le forum Débuter
    Réponses: 3
    Dernier message: 06/02/2008, 13h18
  4. [JNI] Compatibilité de types
    Par rabobsky dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 11/07/2005, 12h01
  5. [Release] Libère réellement la mémoire ?
    Par kase74 dans le forum Langage
    Réponses: 13
    Dernier message: 27/09/2004, 17h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo