Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

3 réponses
Avatar
Luc Hermitte
Bonjour,

Je suis en train de r=E9aliser 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=E0, entre deux appels =E0 la JVM je n'ai pas de raisons de
l'arr=EAter, et avant de l'appeler, je dois obtenir quantit=E9 d'IDs,
initialiser mon param=E8tre (un objet Toto construit =E0 partir de 6
chaines de caract=E8res), et =E0 la sortie je dois r=E9cup=E9rer les chaine=
s
contenues dans un autre objet de type Titi renvoy=E9 par la fonction
Java appel=E9e. =C0 priori, rien de sorcier.

Toujours dans le m=EAme bouquin, je lis que les Ref=E9rences Locales sont
automatiquement collect=E9es =E0 la sortie de la fonction native appel=E9e
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=E9f=E9rences =E0 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) =E0 la JVM de collecter mes
2 objets (le param=E8tre et celui retourn=E9), ainsi que toutes les
chaines interm=E9diaires ?
Dans le m=EAme ordre d'id=E9e faut-il indiquer de lib=E9rer les ID
interm=E9diaires ? (m=EAme si au fond je pourrais les m=E9moriser pour une
utilisation ult=E9rieure)

Si vous avez la r=E9ponse =E0 ces questions, ou une doc qui se pr=E9occupe
plus de ces points, je suis des plus int=E9ress=E9s.
NB: Au cours de mes recherches je suis tomb=E9 sur GIWS dont je vais
analyser les sorties, mais mon int=E9r=EAt est avant tout th=E9orique : je
n'ai pas trouv=E9 d'informations claires et pr=E9cises sur comment la
m=E9moire devait =EAtre g=E9r=E9e 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=E9 sur fclj

--
Luc Hermitte

3 réponses

Avatar
jlp
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
Avatar
Michael DOUBEZ
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
Avatar
Luc Hermitte
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