Je comprends que Rust n'a pas de ramasse-miettes et je me demande comment la mémoire est libérée lorsqu'une liaison est hors de portée.
Donc, dans cet exemple, je comprends que Rust récupère la mémoire allouée à «a» quand il est hors de portée.
{
let a = 4
}
Le problème que j'ai avec cela, c'est d'abord comment cela se produit, et deuxièmement, n'est-ce pas une sorte de garbage collection? En quoi diffère-t-il du ramasse-miettes «typique»?
Réponses:
Le nettoyage de la mémoire est généralement utilisé périodiquement ou à la demande, comme si le tas est presque plein ou au-dessus d'un certain seuil. Il recherche ensuite les variables inutilisées et libère leur mémoire, en fonction de l' algorithme .
Rust saurait quand la variable devient hors de portée ou que sa durée de vie se termine au moment de la compilation et insère ainsi les instructions LLVM / d'assemblage correspondantes pour libérer la mémoire.
Rust permet également une sorte de récupération de place, comme le comptage de références atomiques .
la source
new()
fonction ointe comme C, ce ne sont que des fonctions statiques, et en particulier quelque chose commelet x = MyStruct::new()
crée son objet sur la pile. Le véritable indicateur de l'allocation de tas estBox::new()
(ou l'une des structures qui dépendent de Box).L'idée de base de la gestion des ressources (y compris la mémoire) dans un programme, quelle que soit la stratégie, est que les ressources liées à des «objets» inaccessibles peuvent être récupérées. Au-delà de la mémoire, ces ressources peuvent être des verrous mutex, des descripteurs de fichiers, des sockets, des connexions de base de données ...
Les langages dotés d'un ramasse-miettes analysent périodiquement la mémoire (d'une manière ou d'une autre) pour trouver des objets inutilisés, libèrent les ressources qui leur sont associées et enfin libèrent la mémoire utilisée par ces objets.
Rust n'a pas de GC, comment gère-t-il?
Rust est propriétaire. En utilisant un système de type affine , il suit quelle variable tient toujours un objet et, lorsqu'une telle variable sort de la portée, appelle son destructeur. Vous pouvez voir le système de type affine en vigueur assez facilement:
Rendements:
ce qui illustre parfaitement qu'à tout moment, au niveau de la langue, la propriété est suivie.
Cette propriété fonctionne de manière récursive: si vous avez un
Vec<String>
(c'est-à-dire un tableau dynamique de chaînes), alors chacunString
est détenu par leVec
qui lui-même appartient à une variable ou à un autre objet, etc ... ainsi, lorsqu'une variable sort de la portée, il libère récursivement toutes les ressources qu'il détenait, même indirectement. Dans le cas du,Vec<String>
cela signifie:String
Vec
lui - mêmeAinsi, grâce au suivi de propriété, la durée de vie de TOUS les objets du programme est strictement liée à une (ou plusieurs) variables de fonction, qui finiront par sortir du champ d'application (lorsque le bloc auquel ils appartiennent se termine).
Remarque: c'est un peu optimiste, en utilisant le comptage de références (
Rc
ouArc
) il est possible de former des cycles de références et donc de provoquer des fuites de mémoire, auquel cas les ressources liées au cycle pourraient ne jamais être libérées.la source
Avec un langage dans lequel vous devez gérer manuellement la mémoire, la distinction entre la pile et le tas devient critique. Chaque fois que vous appelez une fonction, suffisamment d'espace est alloué sur la pile pour toutes les variables contenues dans la portée de cette fonction. Lorsque la fonction est renvoyée, le cadre de pile associé à cette fonction est "sauté" hors de la pile et la mémoire est libérée pour une utilisation future.
D'un point de vue pratique, ce nettoyage de mémoire par inadvertance est utilisé comme un moyen de stockage automatique de la mémoire qui sera effacé à la fin de la portée de la fonction.
Il y a plus d'informations disponibles ici: https://doc.rust-lang.org/book/the-stack-and-the-heap.html
la source