Ramasse-miettes Lua

Lua utilise une gestion automatique de la mémoire. Cela signifie que vous n'avez pas à vous soucier de la façon dont la mémoire des objets nouvellement créés est allouée, ni de la façon de libérer la mémoire qu'ils occupent après que les objets ne sont plus utilisés.

Lua exécute unramasse-miettespour collecter tous lesobjets morts(c'est-à-dire les objets qui ne sont plus accessibles dans Lua) afin de mener à bien le travail de gestion automatique de la mémoire. Toute la mémoire utilisée dans Lua, comme les chaînes de caractères, les tables, les données utilisateur, les fonctions, les threads, les structures internes, etc., est soumise à une gestion automatique.

Lua implémente un ramasse-miettes incrémental à marquage et balayage. Il utilise ces deux nombres pour contrôler le cycle de collecte des déchets : le taux de pause du ramasse-miettes et le multiplicateur de pas du ramasse-miettes. Les deux nombres sont en unités de pourcentage (par exemple, la valeur 100 est représentée en interne par 1).

La pause du ramasse-miettes contrôle combien de temps le collecteur doit attendre avant de démarrer un nouveau cycle. Augmenter cette valeur réduit l'empressement du collecteur. Lorsque cette valeur est inférieure à 100, le collecteur n'attendra pas avant de démarrer un nouveau cycle. Définir cette valeur à 200 fera attendre le collecteur jusqu'à ce que l'utilisation totale de la mémoire atteigne le double de la quantité précédente avant de démarrer un nouveau cycle.

Le multiplicateur de pas du ramasse-miettes contrôle la vitesse à laquelle le collecteur opère par rapport au taux d'allocation mémoire. Augmenter cette valeur rend non seulement le collecteur plus agressif, mais augmente également la longueur de chaque pas incrémental. Ne définissez pas cette valeur en dessous de 100, sinon le collecteur travaillera trop lentement et ne terminera jamais un cycle. La valeur par défaut est 200, ce qui signifie que le collecteur travaille à une vitesse "double" de l'allocation mémoire.

Si vous définissez le multiplicateur d'étape sur un nombre très grand (10 % de plus que le nombre d'octets que votre programme pourrait utiliser), le collecteur se comporte comme un collecteur stop-the-world. Ensuite, si vous définissez le taux de pause à 200, le collecteur se comporte comme les versions précédentes de Lua : chaque fois que l'utilisation de la mémoire de Lua double, une collecte complète est effectuée.


Fonctions du ramasse-miettes

Lua fournit les fonctions suivantescollectgarbage ([opt [, arg]])pour contrôler la gestion automatique de la mémoire :

  • collectgarbage("collect"): Effectue un cycle complet de collecte des déchets. Via le paramètre opt, elle fournit un ensemble de fonctions différentes :

  • collectgarbage("count"): Renvoie la mémoire totale utilisée par Lua en K bytes. Cette valeur possède une partie fractionnaire, donc multipliez simplement par 1024 pour obtenir le nombre exact d'octets utilisés par Lua (sauf débordement).

  • collectgarbage("restart"): Redémarre le fonctionnement automatique du ramasse-miettes.

  • collectgarbage("setpause"): Définit arg comme le taux de pause du collecteur. Renvoie la valeur précédente du taux de pause.

  • collectgarbage("setstepmul"): Renvoie la valeur précédente du multiplicateur d'étape.

  • collectgarbage("step"): Exécute le ramasse-miettes en une seule étape. La "taille" de l'étape est contrôlée par arg. Lorsque 0 est passé, le collecteur effectue une étape (indivisible). Lorsqu'une valeur non nulle est passée, le collecteur effectue un travail équivalent à Lua allouant cette quantité de mémoire (K bytes). Si le collecteur termine un cycle, il renvoie true.

  • collectgarbage("stop"): Arrête le fonctionnement du ramasse-miettes. Tant que restart n'est pas appelé, le collecteur ne s'exécutera que lorsqu'il est explicitement invoqué.

Ce qui suit présente un exemple simple de ramasse-miettes :

Exemple

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

Exécutez le programme ci-dessus, la sortie est la suivante (notez la variation de l'utilisation de la mémoire) :

20.9560546875
20.9853515625
0
19.4111328125
Autres extensions