You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 445 Reporter: administrator Status: closed Resolution: won't fix Priority: normal Severity: feature Category: ~DO NOT USE (was: OCaml general)
Bug description
Bonjour,
les modules (code + données globales) chargés dynamiquement par Dynlink ne
sont jamais liberés par le GC, même si le chargeur ne garde aucune
référence à ces données globales et aucune fermeture qui tombe
dans le code du module. Par exemple, cela rend Dynlink inutilisable
pour un serveur http qui chargerait des .cmo pour traiter des requetes
CGI.
Ce serait peut-être utile de signaler ce comportement dans le manuel:
quand on utilise Caml, on a tendance à se reposer sur le GC; et
le genre d'utilisation citée ci-dessus semble assez naturelle pour
Dynlink. Une autre situation où j'aurais voulu utiliser Dynlink,
c'est la reconfiguration d'un programme à l'execution (on lui envoie
un signal qui lui demande de recharger un fichier de config, qui peut
contenir du code, etc ...); là encore, problème.
Serait-il envisageable de donner la possibilité de liberer
effectivement des modules chargés ? Dans le système actuel, il y a deux
choses qui rendent cela difficile:
les blocs de codes ne sont pas sous le controle du GC; la solution
immédiate est d'utiliser String.create au lieu de Meta.static_alloc
dans dynlink.ml, et de faire en sorte que le GC qui suit le pointeur
vers le code d'une fermeture puisse retrouver le début du bloc
de code (cela peut se faire avec une table qui permet de retrouver
rapidemment cette information, ou alors en insérant juste avant les
labels qui servent de point d'entrée à des fermetures
un opcode inerte qui indique le déplacement pour retrouver le début du
bloc, un peu dans le genre des Infix_tag). Une variante,
c'est de garder des blocs statiques pour le code. Si le surcout
pour le GC est trop important, ce serait bien de pouvoir au moins
garder un "handle" sur les modules chargés, et de pouvoir demander
explicitement leur libération; à ce moment, il suffit de lancer
un parcours du style GC, mais qui teste juste si dans les fermetures
rencontrées, il y a des pointeurs vers du code dans la zone qui correspond
au module que l'on veut libérer (et lève une exception si c'est le cas).
Cette solution a l'avantage de ne pas toucher au code du GC,
et d'être locale à Dynlink.
une fois la décision prise de libérer le code associé à un module
chargé dynamiquement, il faut aussi libérer les entrées
correspondantes dans la table des données globales. Pour éviter
que la table soit pleine de trous, on peut par exemple utiliser
classiquement une liste chainée des trous (free list) et redonner ces
entrées aux prochains modules chargés.
Est-ce qu'il y a autre chose à prendre en compte ?
Même avec la libération explicite, ça ajouterait beaucoup d'interêt à
Dynlink.
Cordialement,
Alain Frisch
The text was updated successfully, but these errors were encountered:
les modules (code + données globales) chargés dynamiquement par Dynlink ne
sont jamais liberés par le GC, même si le chargeur ne garde aucune
référence à ces données globales et aucune fermeture qui tombe
dans le code du module.
C'est exact.
Par exemple, cela rend Dynlink inutilisable
pour un serveur http qui chargerait des .cmo pour traiter des requetes
CGI.
Si le .cmo est chargé puis déchargé à chaque requête, oui -- mais ce
ne me semble pas être un très bon modèle pour un serveur HTTP :-)
Si les moduels sont chargés uniquement au démarrage du processus
(comme les modules d'Apache), cela reste utilisable.
Serait-il envisageable de donner la possibilité de liberer
effectivement des modules chargés ?
Ton analyse est correcte: la principale difficulté est de faire du GC
sur le code, ce qui signifie traiter les pointeurs infixes dans les
blocs de code que l'on trouve sur la pile. Ce n'est pas impossible en
principe, mais bien compliqué! La libération explicite est un poil
plus simple, mais le parcours "genre GC" du graphe mémoire qu'elle
nécessite est aussi un problème, car on n'a pas accès aux bits de
marque du GC pour garder trace des endroits où on est déjà passé dans
le graphe mémoire.
Bref, je me vois mal implémenter cela dans un futur proche :-)
Original bug ID: 445
Reporter: administrator
Status: closed
Resolution: won't fix
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)
Bug description
Bonjour,
les modules (code + données globales) chargés dynamiquement par Dynlink ne
sont jamais liberés par le GC, même si le chargeur ne garde aucune
référence à ces données globales et aucune fermeture qui tombe
dans le code du module. Par exemple, cela rend Dynlink inutilisable
pour un serveur http qui chargerait des .cmo pour traiter des requetes
CGI.
Ce serait peut-être utile de signaler ce comportement dans le manuel:
quand on utilise Caml, on a tendance à se reposer sur le GC; et
le genre d'utilisation citée ci-dessus semble assez naturelle pour
Dynlink. Une autre situation où j'aurais voulu utiliser Dynlink,
c'est la reconfiguration d'un programme à l'execution (on lui envoie
un signal qui lui demande de recharger un fichier de config, qui peut
contenir du code, etc ...); là encore, problème.
Serait-il envisageable de donner la possibilité de liberer
effectivement des modules chargés ? Dans le système actuel, il y a deux
choses qui rendent cela difficile:
les blocs de codes ne sont pas sous le controle du GC; la solution
immédiate est d'utiliser String.create au lieu de Meta.static_alloc
dans dynlink.ml, et de faire en sorte que le GC qui suit le pointeur
vers le code d'une fermeture puisse retrouver le début du bloc
de code (cela peut se faire avec une table qui permet de retrouver
rapidemment cette information, ou alors en insérant juste avant les
labels qui servent de point d'entrée à des fermetures
un opcode inerte qui indique le déplacement pour retrouver le début du
bloc, un peu dans le genre des Infix_tag). Une variante,
c'est de garder des blocs statiques pour le code. Si le surcout
pour le GC est trop important, ce serait bien de pouvoir au moins
garder un "handle" sur les modules chargés, et de pouvoir demander
explicitement leur libération; à ce moment, il suffit de lancer
un parcours du style GC, mais qui teste juste si dans les fermetures
rencontrées, il y a des pointeurs vers du code dans la zone qui correspond
au module que l'on veut libérer (et lève une exception si c'est le cas).
Cette solution a l'avantage de ne pas toucher au code du GC,
et d'être locale à Dynlink.
une fois la décision prise de libérer le code associé à un module
chargé dynamiquement, il faut aussi libérer les entrées
correspondantes dans la table des données globales. Pour éviter
que la table soit pleine de trous, on peut par exemple utiliser
classiquement une liste chainée des trous (free list) et redonner ces
entrées aux prochains modules chargés.
Est-ce qu'il y a autre chose à prendre en compte ?
Même avec la libération explicite, ça ajouterait beaucoup d'interêt à
Dynlink.
Cordialement,
Alain Frisch
The text was updated successfully, but these errors were encountered: