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

adresse mémoire et LibXML

4 réponses
Avatar
mzi
Bonjour à tous,

Il est possible, avec &Scalar::Util::refaddr($ref), de trouver l'adresse
mémoire d'une référence. Ma question est la suivante: peut-on se servir de
cette adresse pour effacer la référence?

Pourquoi? me direz-vous. En fait, je me sers de XML::LibXML, qui est un
emballage de libxml2 en perl. Dans ce module, la fonction qui permet
d'effacer des éléments ne les efface pas réellement: elle les place dans un
objet "invisible" qui est un DocumentFragment, qui est lié au Document.
Pour effacer ce fragment, il faut sortir de la portée du Document... donc
perdre tout le reste. Je vous laisse imaginer ce que ça donne en termes de
fuites de mémoire.

Quelqu'un a une idée?

--
mzi

4 réponses

Avatar
Paul Gaborit
À (at) Tue, 06 Jun 2006 11:26:52 +0200,
mzi écrivait (wrote):
Il est possible, avec &Scalar::Util::refaddr($ref), de trouver l'adresse
mémoire d'une référence. Ma question est la suivante: peut-on se se rvir de
cette adresse pour effacer la référence?


En Perl, a priori, je dirais que cette adresse ne sert à rien.
Évidemment, on peut peut-être en faire quelque chose en C mais encore
faudrait-il connaître l'allocateur utilisé. Note: ce n'est pas
l'adresse mémoire de la référence mais l'adresse mémoire de ce qui est
référencé. De plus, c'est risqué d'effacer cet espace mémoire car il y
a peut-être d'autres objets qui référencent ce même espace mémoir e...

Pourquoi? me direz-vous. En fait, je me sers de XML::LibXML, qui est un
emballage de libxml2 en perl. Dans ce module, la fonction qui permet
d'effacer des éléments ne les efface pas réellement: elle les place dans un
objet "invisible" qui est un DocumentFragment, qui est lié au Document.
Pour effacer ce fragment, il faut sortir de la portée du Document... do nc
perdre tout le reste. Je vous laisse imaginer ce que ça donne en termes de
fuites de mémoire.

Quelqu'un a une idée?


J'ai l'impression, sans en être sûr, que c'est le fonctionnement
interne de libxml2 qui définit ce comportement et que les modules Perl
ne font que donner un accès à ces couches basses. Avez-vous un exemple
simple de code qui montre ce comportement ? Même si la documentation
de XML::LibXML::DocumentFragment n'est pas vraiment claire, la
documentation de la méthode 'removeChildNodes' de XML::LibXML::Node
semble tout de même indiquer que la mémoire sera bien libérée à un
moment ou à un autre...

Un moyen simple mais un peu lourd de s'en sortir consisterait à cloner
le document original (en ne recopiant que les éléments réellement
atachés à l'arbre) puis à détruire l'original en ne conservant que le
clone...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
mzi
Paul Gaborit wrote:

Ma question est la suivante: peut-on se servir
de cette adresse pour effacer la référence?


De plus, c'est risqué d'effacer cet espace mémoire car il y
a peut-être d'autres objets qui référencent ce même espace mémoire...


D'accord: il vaut mieux laisser faire Perl, donc.

J'ai l'impression, sans en être sûr, que c'est le fonctionnement
interne de libxml2 qui définit ce comportement et que les modules Perl
ne font que donner un accès à ces couches basses. Avez-vous un exemple
simple de code qui montre ce comportement ?


En faisant l'exemple en LibXML, je viens de remarquer que la fuite n'était
pas due à LibXML mais à mon code (je créais une référence circulaire à
l'objet enlevé). Je retourne au boulot. Désolé.

--
mzi


Avatar
Paul Gaborit
À (at) Tue, 06 Jun 2006 13:50:13 +0200,
mzi écrivait (wrote):
D'accord: il vaut mieux laisser faire Perl, donc.


Su ce genre de choses (la gestion mémoire) et si on ne crée pas de
références circulaires, Perl est quasi parfait.

En faisant l'exemple en LibXML, je viens de remarquer que la fuite n'ét ait
pas due à LibXML mais à mon code (je créais une référence circu laire à
l'objet enlevé). Je retourne au boulot.


Hé oui. C'est souvent comme ça qu'on trouve les bugs : même ceux qu'on
n'avait pas encore détectés ;-)

Désolé.


Pas de quoi. Heureux d'avoir pu rendre service.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
espie
In article <e63q5l$pgm$, mzi wrote:

En faisant l'exemple en LibXML, je viens de remarquer que la fuite n'était
pas due à LibXML mais à mon code (je créais une référence circulaire à
l'objet enlevé). Je retourne au boulot. Désolé.


Une petite recherche sur le mot-cle `weakref' sur un site CPAN renvoie
des merveilles...

Dont XML::Twig

Sinon, dans tous les perls recents, la lecture de la doc de Scalar::Util
explique assez bien tous ces problemes de references circulaires
qui empechent le GC de faire son boulot, et les solutions fournies par le
langage.