Maison > Article > développement back-end > La langue go a-t-elle un ramasse-miettes ?
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.
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.
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
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 :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
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 :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 tasLinear 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 Par conséquent, l'allocateur linéaire doit être utilisé en conjonction avec un algorithme de récupération de place approprié
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éeIl existe quatre stratégies courantes pour les allocateurs de listes chaînées gratuites :
dans le langage Go, tous les objets du tas alloueront de la mémoire en appelant la fonction
runtime.newobject, 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
(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, +∞)
— 直接在堆上分配内存小分配
对于小于 32kb 的小分配,Go 会尝试从 mcache
的本地缓存中获取内存,该缓存处理一个跨度列表 (32kb 的内存块) mspan
每个线程 M 都分配给一个处理器 P,一次最多处理一个 goroutine
。在分配内存时,当前的 goroutine
将使用其当前的本地缓存 P 来查找 span
Petits 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>
Petites allocations
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) mspan
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
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
2. Garbage collection
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"
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
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
_GCmarktermination et fermez le programme utilisateur auxiliaire marqué <li>Nettoyez le cache des threads sur le processeur
_GCoff code> Démarrer la phase de nettoyage, initialiser l'état de nettoyage et désactiver la barrière en écriture<p></p>
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!