Maison  >  Article  >  développement back-end  >  La langue go a-t-elle un ramasse-miettes ?

La langue go a-t-elle un ramasse-miettes ?

青灯夜游
青灯夜游original
2022-12-09 19:42:387004parcourir

Go Language a un ramassage des ordures. Le langage Go est livré avec un mécanisme de récupération de place (GC) ; GC est exécuté via un processus distinct. Il recherche les variables qui ne sont plus utilisées et les libère. dans le calcul. L'espace mémoire contient deux zones importantes : la zone de pile (Stack) et la zone de tas (Heap) ; la zone de pile stocke généralement les paramètres, les valeurs de retour et les variables locales des appels de fonction, ne produit pas de fragmentation de la mémoire, est gérée par le compilateur, et ne nécessite pas de développement. La zone de tas générera des fragments de mémoire. Dans le langage Go, les objets de la zone de tas sont alloués par l'allocateur de mémoire et recyclés par le garbage collector.

La langue go a-t-elle un ramasse-miettes ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, GO version 1.18, ordinateur Dell G3.

Le langage Go est livré avec son propre mécanisme de collecte des ordures (GC). Le GC est effectué par un processus distinct, qui recherche les variables qui ne sont plus utilisées et les libère. Il convient de noter que GC occupera les ressources de la machine lors de son exécution.

Explication détaillée du mécanisme de garbage collection GC dans le langage Go

En informatique, le garbage collection (Garbage Collection (GC) en abrégé) est un mécanisme de gestion automatique de la mémoire. Le garbage collector va tenter de recycler. Le programme et ne l'utilise plus. Objets et mémoire occupée

Les programmeurs bénéficient du GC. Ils n'ont plus à s'inquiéter et n'ont plus besoin de demander et de libérer manuellement la mémoire. GC libère automatiquement la mémoire restante lorsque le programme est exécuté. en cours d'exécution. GC est presque invisible pour les programmeurs. , seulement lorsque le programme nécessite une optimisation spéciale, il peut apparaître en fournissant une API contrôlable pour contrôler le timing d'exécution et la surcharge d'exécution de GC

En informatique, l'espace mémoire contient deux zones importantes : La zone de pile (Stack) et la zone de tas (Heap) ; la zone de pile stocke généralement les paramètres, les valeurs de retour et les variables locales des appels de fonction, ne produit pas de fragmentation de la mémoire, est gérée par le compilateur et ne nécessite pas de développeur. gestion ; tandis que la zone de tas génère une fragmentation de la mémoire. Dans le langage Go, les objets de la zone de tas sont alloués par l'allocateur de mémoire et recyclés par le garbage collector. [Recommandations associées :

Tutoriel vidéo Go, Enseignement de la programmation]

Habituellement, le processus d'exécution du garbage collector est divisé en deux composants semi-indépendants :

    Programme utilisateur (Mutator) : code en mode utilisateur, pour GC et En d'autres termes, le code du mode utilisateur ne fait que modifier la relation de référence entre les objets
  • Collector (Collector) : le code responsable de l'exécution du garbage collection

1. Gestion et allocation de la mémoire

Lorsque la mémoire n'est plus disponible Lorsqu'elle est utilisée, la gestion de la mémoire Go est automatiquement effectuée par sa bibliothèque standard, c'est-à-dire l'allocation de la mémoire aux collections Go. La gestion de la mémoire comprend généralement trois composants différents, à savoir le programme utilisateur (Mutator), l'allocateur (Allocator) et le collecteur (Collector). Lorsque le programme utilisateur demande de la mémoire, il demandera une nouvelle mémoire via l'allocateur de mémoire et l'allocateur. Sera chargé d'initialiser la zone mémoire correspondante à partir du tas

La langue go a-t-elle un ramasse-miettes ?

1.1 Méthode d'allocation de l'allocateur de mémoire

Dans les langages de programmation, les allocateurs de mémoire ont généralement deux méthodes d'allocation :

  • Allocateur linéaire (Sequential Allocator , Bump Allocator)

  • Free-List Allocator (Free-List Allocator)

Linear Allocator

L'allocation linéaire (Bump Allocator) est une méthode d'allocation de mémoire efficace, mais elle présente certains inconvénients et de grandes limitations. Lorsque l'utilisateur utilise un allocateur linéaire, il lui suffit de maintenir un pointeur vers un emplacement mémoire spécifique dans la mémoire. Si le programme utilisateur demande de la mémoire à l'allocateur, l'allocateur n'a qu'à vérifier la mémoire libre restante et à renvoyer la mémoire allouée. zone et modifiez le pointeur dans Emplacement en mémoire ;

Bien que l'allocateur linéaire ait une vitesse d'exécution plus rapide et une complexité de mise en œuvre inférieure, l'allocateur linéaire ne peut pas réutiliser la mémoire une fois la mémoire libérée. Comme indiqué ci-dessous, si la mémoire allouée est recyclée, l'allocateur linéaire ne peut pas réutiliser la mémoire rouge

La langue go a-t-elle un ramasse-miettes ?

Par conséquent, l'allocateur linéaire doit être utilisé en conjonction avec un algorithme de récupération de place approprié

  • Mark-Compact

  • Copie de GC

  • GC générationnel

L'algorithme ci-dessus peut défragmenter les objets survivants en copiant et fusionner régulièrement la mémoire libre, afin que l'allocateur linéaire puisse être utilisé. L'efficacité améliore les performances de l'allocateur de mémoire

Free-List Allocator

Free-List Allocator (Free-List Allocator) peut réutiliser la mémoire qui a été libérée. Il maintient une structure de données similaire à une liste chaînée en interne. Lorsqu'un programme utilisateur demande de la mémoire, l'allocateur de liste chaînée libre parcourra les blocs de mémoire libres afin de trouver une mémoire suffisamment grande, puis demandera de nouvelles ressources et modifiera la liste chaînée

La langue go a-t-elle un ramasse-miettes ?

Il existe quatre stratégies courantes pour les allocateurs de listes chaînées gratuites :

  • First-Fit - parcourez à partir de la tête de la liste chaînée et sélectionnez le premier bloc de mémoire avec une taille supérieure à la mémoire demandée
  • Loop First-Fit (Next-Fit) — Parcourez à partir de la position finale du dernier parcours et sélectionnez le premier bloc de mémoire dont la taille est supérieure à la mémoire demandée (Best-Fit) — Parcourez toute la liste chaînée à partir de la tête du. liste chaînée et sélectionnez le bloc de mémoire le plus approprié - Divisez la mémoire en plusieurs listes chaînées. Lors de la demande de mémoire, recherchez d'abord une liste chaînée qui répond aux conditions. , puis sélectionnez le bloc de mémoire approprié dans la liste chaînée
  • La stratégie quatre-en-un est similaire à la stratégie d'allocation de mémoire utilisée dans le langage Go

Cette stratégie divisera la mémoire en une liste chaînée. composé de blocs de mémoire de 4, 8, 16 et 32 ​​octets Lorsque nous demandons 8 octets de mémoire à l'allocateur de mémoire, il trouvera le bloc de mémoire libre qui remplit les conditions de la figure ci-dessus et reviendra. La stratégie d'allocation d'adaptation à l'isolement réduit le nombre de blocs de mémoire à parcourir et améliore l'efficacité de l'allocation de mémoire

La langue go a-t-elle un ramasse-miettes ?

1.2 Allocation de mémoire dans Go

Une image montre la composition de l'allocation de mémoire :

dans le langage Go, tous les objets du tas alloueront de la mémoire en appelant la fonction

runtime.newobjectLa langue go a-t-elle un ramasse-miettes ?, qui appellera

runtime.mallocgc

pour allouer un espace mémoire d'une taille spécifiée. C'est également une fonction nécessaire pour l'utilisateur. programmes pour demander de l'espace mémoire sur le tas

func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
	mp := acquirem()
	mp.mallocing = 1

	c := gomcache()
	var x unsafe.Pointer
	noscan := typ == nil || typ.ptrdata == 0
	if size 
On peut voir dans le code que runtime.mallocgc effectue différentes logiques d'allocation en fonction de la taille de l'objet, et les divise en micro-objets, petits objets et gros objets en fonction de la taille de l'objet

Micro objets (0, 16B) — Utilisez d'abord le micro allocateur, puis essayez d'utiliser le cache de threads, le cache central et le tas pour allouer de la mémoire

runtime.mallocgc 根据对象的大小执行不同的分配逻辑,根据对象大小将它们分成微对象、小对象和大对象

  • 微对象 (0, 16B) — 先使用微型分配器,再依次尝试线程缓存、中心缓存和堆分配内存
  • 小对象 [16B, 32KB] — 依次尝试使用线程缓存、中心缓存和堆分配内存
  • 大对象 (32KB, +∞) — 直接在堆上分配内存

La langue go a-t-elle un ramasse-miettes ?

小分配

对于小于 32kb 的小分配,Go 会尝试从 mcache 的本地缓存中获取内存,该缓存处理一个跨度列表 (32kb 的内存块) mspan

La langue go a-t-elle un ramasse-miettes ?

每个线程 M 都分配给一个处理器 P,一次最多处理一个 goroutine。在分配内存时,当前的 goroutine 将使用其当前的本地缓存 P 来查找 spanPetits objets [16B, 32KB] — Essayez d'utiliser tour à tour le cache de threads, le cache central et la mémoire allouée au tas

Grand objet (32KB, +∞) — alloue de la mémoire directement sur le tas<strong></strong>

La langue go a-t-elle un ramasse-miettes ?

Petites allocationsLa langue go a-t-elle un ramasse-miettes ?

Pour les petites allocations inférieures à 32 Ko, Go essaiera de démarrer à partir de mcache, qui gère une liste de span (bloc mémoire de 32 Ko) mspanLa langue go a-t-elle un ramasse-miettes ?Chaque thread M est affecté à un processeur P, et peut en traiter au plus un à la foisgoroutine. Lors de l'allocation de mémoire, la goroutine actuelle utilisera son cache local actuel P pour trouver le premier objet libre disponible dans la liste span

Big Allocation

Go ne utilisez le cache local pour gérer des allocations importantes. Ces allocations supérieures à 32 Ko sont arrondies à la taille de la page, et la page est allouée directement au tas

La langue go a-t-elle un ramasse-miettes ?

2. Garbage collection

Dans le langage Go, l'algorithme implémenté par le garbage collector est un collecteur de marquage et de numérisation tridimensionnel simultané Le ramasse-miettes s'exécute en même temps que le programme Go, donc un algorithme de

barrière d'écriture

est nécessaire pour détecter les changements potentiels dans la mémoire. La seule condition pour initier une barrière en écriture est d'arrêter le programme pendant une courte période, c'est-à-dire "Stop the World"

La langue go a-t-elle un ramasse-miettes ?

Le but de la barrière en écriture est de permettre au collecteur de maintenir l'intégrité des données sur le tas pendant la collecte

  • 2.1 Principe de mise en œuvre

Le garbage collection du langage Go peut être divisé en quatre phases différentes : terminaison claire, marquage, terminaison de marque et effacement, dont deux généreront Stop The World (STW)

🎜🎜🎜phase de fin d'effacement🎜 🎜🎜🎜Mettez le programme en pause, tous les processeurs entreront dans le point de sécurité à ce moment-là 🎜🎜Si le cycle de récupération de place actuel est déclenché de force, nous devons également nous occuper de l'unité de gestion de la mémoire qui n'a pas été nettoyé🎜🎜🎜🎜mark Stage (STW)🎜🎜
  • Basculez le statut sur _GCmark, activez les barrières d'écriture, l'assistance au programme utilisateur (Mutator Assists) et mettez l'objet racine en file d'attente _GCmark、开启写屏障、用户程序协助(Mutator Assists)并将根对象入队

  • 恢复执行程序,标记进程和用于协助的用户程序会开始并发标记内存中的对象,写屏障会将被覆盖的指针和新指针都标记成灰色,而所有新创建的对象都会被直接标记成黑色

  • 开始扫描根对象,包括所有 Goroutine 的栈、全局对象以及不在堆中的运行时数据结构,扫描 Goroutine 栈期间会暂停当前处理器

  • 依次处理灰色队列中的对象,将对象标记成黑色并将它们指向的对象标记成灰色

  • 使用分布式的终止算法检查剩余的工作,发现标记阶段完成后进入标记终止阶段

标记终止阶段 (STW)

  • 暂停程序、将状态切换至 _GCmarktermination 并关闭辅助标记的用户程序
  • 清理处理器上的线程缓存

清理阶段

  • 将状态切换至 _GCoff

  • Reprenez le programme d'exécution, marquez le processus et le programme utilisateur pour assistance Commencera à marquer simultanément les objets dans la mémoire, la barrière d'écriture marquera les pointeurs écrasés et les nouveaux pointeurs en gris, et tous les objets nouvellement créés seront directement marqués en noir

  • Commencez à analyser l'objet racine, y compris toute la pile de Goroutine. , les objets globaux et les structures de données d'exécution qui ne sont pas dans le tas, le processeur actuel sera mis en pause pendant l'analyse de la pile Goroutine

Traitez tour à tour les objets dans la file d'attente grise, marquez les objets en noir et marquez les objets vers lesquels ils pointent en gris

Utilisez l'algorithme de terminaison distribuée pour vérifier le travail restant et constatez qu'une fois la phase de marquage terminée, il entre dans la phase de terminaison du marquage

    phase de terminaison du marquage (STW)
  • Mettre le programme en pause et changez l'état sur _GCmarktermination et fermez le programme utilisateur auxiliaire marqué <li>Nettoyez le cache des threads sur le processeur

    Phase de nettoyage
  • Changez l'état sur _GCoff code> Démarrer la phase de nettoyage, initialiser l'état de nettoyage et désactiver la barrière en écriture<p></p>
  • Restaurer le programme utilisateur, tous les objets nouvellement créés seront marqués en blanc

Nettoyer simultanément toutes les unités de gestion de mémoire en arrière-plan, lorsque Goroutine demande une nouvelle unité de gestion de mémoire, le nettoyage sera déclenché

1La langue go a-t-elle un ramasse-miettes ?

2.2 Méthode de marquage à trois couleurs🎜🎜🎜L'algorithme de marquage à trois couleurs divise les objets du programme en trois catégories : blanc, noir et gris : 🎜🎜🎜Objets blancs - déchets potentiels, dont la mémoire peut être récupérée par le garbage collector🎜🎜 Objets noirs - objets actifs, y compris les objets qui n'ont aucune référence à des pointeurs externes et les objets accessibles depuis l'objet racine 🎜🎜 Objets gris - objets actifs, car il y a des pointeurs externes pointant vers des objets blancs, le garbage collector analysera ces objets Sous-objet 🎜🎜🎜Le principe de fonctionnement du garbage collector à marquage tricolore est simple et peut être résumé dans les étapes suivantes : 🎜🎜 🎜🎜Sélectionnez un objet gris dans la collection d'objets gris et marquez-le en noir 🎜🎜🎜 🎜Marquez tous les objets pointés par l'objet noir comme gris pour garantir que ni l'objet ni les objets référencés par l'objet ne seront recyclés🎜🎜🎜 🎜Répétez les deux étapes ci-dessus jusqu'à ce qu'il n'y ait plus d'objets gris dans le graphique d'objets🎜🎜🎜🎜🎜 🎜🎜Pour plus de connaissances sur la programmation, veuillez visiter : 🎜Vidéos de programmation🎜 ! ! 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn