[JNI] C++ -> Java, et libération des références locales
3 réponses
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.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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.
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
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.
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
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.
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
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.
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 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.
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.
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.
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
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
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.
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.