[JNI] C++ -> Java, et libération des références locales

Le
Luc Hermitte
Bonjour,

Je suis en train de réaliser un appel du C++ vers le Java.
En suivant, le chapitre /The Invocation Interface/ [*] du /JNI
Programmer's Guide and Specification/ je m'en sors.

Seulement voilà, entre deux appels à la JVM je n'ai pas de raisons de
l'arrêter, et avant de l'appeler, je dois obtenir quantité d'IDs,
initialiser mon paramètre (un objet Toto construit à partir de 6
chaines de caractères), et à la sortie je dois récupérer les chaine=
s
contenues dans un autre objet de type Titi renvoyé par la fonction
Java appelée. À priori, rien de sorcier.

Toujours dans le même bouquin, je lis que les Reférences Locales sont
automatiquement collectées à la sortie de la fonction native appelée
depuis Java. Sauf que je suis dans l'autre situation: ce n'est pas
Java qui m'enveloppe, il ne peut donc pas savoir qu'il peut collecter
les références à la sortie de la fonction native qu'il appelle, vu qu=
e
c'est la fonction native qui appelle Java.

Comment (/dois-) dire (proprement j'entends) à la JVM de collecter mes
2 objets (le paramètre et celui retourné), ainsi que toutes les
chaines intermédiaires ?
Dans le même ordre d'idée faut-il indiquer de libérer les ID
intermédiaires ? (même si au fond je pourrais les mémoriser pour une
utilisation ultérieure)

Si vous avez la réponse à ces questions, ou une doc qui se préoccupe
plus de ces points, je suis des plus intéressés.
NB: Au cours de mes recherches je suis tombé sur GIWS dont je vais
analyser les sorties, mais mon intérêt est avant tout théorique : je
n'ai pas trouvé d'informations claires et précises sur comment la
mémoire devait être gérée dans mon cas.

Merci.

[*] http://java.sun.com/docs/books/jni/html/invoke.html#11202


PS: J'ai fais un x-post fclc++, fclj avec fu2 positionné sur fclj

--
Luc Hermitte
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
jlp
Le #19150021
Luc Hermitte a écrit :
Bonjour,

Je suis en train de réaliser un appel du C++ vers le Java.
En suivant, le chapitre /The Invocation Interface/ [*] du /JNI
Programmer's Guide and Specification/ je m'en sors.

Seulement voilà, entre deux appels à la JVM je n'ai pas de raisons de
l'arrêter, et avant de l'appeler, je dois obtenir quantité d'IDs,
initialiser mon paramètre (un objet Toto construit à partir de 6
chaines de caractères), et à la sortie je dois récupérer les chaines
contenues dans un autre objet de type Titi renvoyé par la fonction
Java appelée. À priori, rien de sorcier.

Toujours dans le même bouquin, je lis que les Reférences Locales sont
automatiquement collectées à la sortie de la fonction native appelée
depuis Java. Sauf que ... je suis dans l'autre situation: ce n'est pas
Java qui m'enveloppe, il ne peut donc pas savoir qu'il peut collecter
les références à la sortie de la fonction native qu'il appelle, vu que
c'est la fonction native qui appelle Java.

Comment (/dois-) dire (proprement j'entends) à la JVM de collecter mes
2 objets (le paramètre et celui retourné), ainsi que toutes les
chaines intermédiaires ?
Dans le même ordre d'idée faut-il indiquer de libérer les ID
intermédiaires ? (même si au fond je pourrais les mémoriser pour une
utilisation ultérieure)

Si vous avez la réponse à ces questions, ou une doc qui se préoccupe
plus de ces points, je suis des plus intéressés.
NB: Au cours de mes recherches je suis tombé sur GIWS dont je vais
analyser les sorties, mais mon intérêt est avant tout théorique : je
n'ai pas trouvé d'informations claires et précises sur comment la
mémoire devait être gérée dans mon cas.

Merci.

[*] http://java.sun.com/docs/books/jni/html/invoke.html#11202


PS: J'ai fais un x-post fclc++, fclj avec fu2 positionné sur fclj

--
Luc Hermitte


Pas de réponse directe, mais sur la JVM tu peux mettre un profiler qui
va suivre les instances de tes objets et vérifier s'ils sont gabagés.
Ou autre solution un peu moins rapide, si tu ne peux pas installer un
profiler, tu mets le gc en verbose log sur la JVM pour voir si tu
détecte une fuite mémoire.
A noter qu'avec le jdk de la JVM SUN 1.6.0_11 et + est fourni le
profiler jvisualvm (évolution de Netbean/JFluid) qui permet d'attacher
en local ce profiler à la JVM
Michael DOUBEZ
Le #19150181
Luc Hermitte wrote:
Bonjour,

Je suis en train de réaliser un appel du C++ vers le Java.
En suivant, le chapitre /The Invocation Interface/ [*] du /JNI
Programmer's Guide and Specification/ je m'en sors.

Seulement voilà, entre deux appels à la JVM je n'ai pas de raisons de
l'arrêter, et avant de l'appeler, je dois obtenir quantité d'IDs,
initialiser mon paramètre (un objet Toto construit à partir de 6
chaines de caractères), et à la sortie je dois récupérer les chaines
contenues dans un autre objet de type Titi renvoyé par la fonction
Java appelée. À priori, rien de sorcier.

Toujours dans le même bouquin, je lis que les Reférences Locales sont
automatiquement collectées à la sortie de la fonction native appelée
depuis Java. Sauf que ... je suis dans l'autre situation: ce n'est pas
Java qui m'enveloppe, il ne peut donc pas savoir qu'il peut collecter
les références à la sortie de la fonction native qu'il appelle, vu que
c'est la fonction native qui appelle Java.

Comment (/dois-) dire (proprement j'entends) à la JVM de collecter mes
2 objets (le paramètre et celui retourné), ainsi que toutes les
chaines intermédiaires ?
Dans le même ordre d'idée faut-il indiquer de libérer les ID
intermédiaires ? (même si au fond je pourrais les mémoriser pour une
utilisation ultérieure)

Si vous avez la réponse à ces questions, ou une doc qui se préoccupe
plus de ces points, je suis des plus intéressés.
NB: Au cours de mes recherches je suis tombé sur GIWS dont je vais
analyser les sorties, mais mon intérêt est avant tout théorique : je
n'ai pas trouvé d'informations claires et précises sur comment la
mémoire devait être gérée dans mon cas.

Merci.

[*] http://java.sun.com/docs/books/jni/html/invoke.html#11202




DeleteLocalRef() doir être ta réponse.

Du même site:
http://java.sun.com/docs/books/jni/html/pitfalls.html

10.6 Confusing IDs with References

The JNI exposes objects as references. Classes, strings, and arrays are
special types of references. The JNI exposes methods and fields as IDs.
An ID is not a reference. Do not call a class reference a "class ID" or
a method ID a "method reference."

References are virtual machine resources that can be managed explicitly
by native code. The JNI function DeleteLocalRef, for example, allows
native code to delete a local reference. In contrast, field and method
IDs are managed by the virtual machine and remain valid until their
defining class is unloaded. Native code cannot explicitly delete a field
or method ID before the the virtual machine unloads the defining class.

--
Michael
Luc Hermitte
Le #19323591
Merci à vous deux pour vos pistes et informations.

Après expérimentations, j'en suis arrivé à la conclusion que :
- effectivement il n'y a rien à faire pour les id
- toutes les références locales créées côté C++ (qui appelle Ja va et
non le contraire) peuvent être libérées (et probablement doivent vu c e
que j'ai pu lire sur le sujet), de même que les références globales.

Du coup j'en suis arrivé à me définir des petits wrapper RAII-sants à
la va-vite pour me simplifier les fuites en situation exceptionnelle.

Accessoirement, pour info et archive, il faut savoir que les symboles
(fonctions) définis dans l'exécutable ne peuvent effectivement pas
être chargés avec un loadlibrary depuis le Java. C'est au côté C++
d'enregistrer ces symboles à l'aide de RegisterNatives -- information
qui est certes disponible dans la version en ligne du manuel, mais qui
est complètement enterrée dans la version pdf qui est un peu plus
vieillotte.

--
Luc Hermitte
Publicité
Poster une réponse
Anonyme