Colección de citas famosas - Slogan de motivación - Asignación de memoria, limpieza y reciclaje de memoria en Golang 1.14

Asignación de memoria, limpieza y reciclaje de memoria en Golang 1.14

La asignación de memoria de Golang se completa mediante el tiempo de ejecución de golang y su esquema de asignación de memoria se basa en tcmalloc.

La característica principal es que

El elemento de este artículo se refiere a un bloque de memoria de cierto tamaño, que es el concepto de asignación de memoria que aparece en el código fuente del tiempo de ejecución de Golang. .

Este artículo describe la asignación de memoria bajo la arquitectura x8664.

La asignación de memoria de Golang tiene las siguientes estructuras principales.

Un objeto pequeño se refiere a un objeto cuyo tamaño de memoria es inferior a 16 B. La asignación de este objeto se realiza utilizando el área pequeña de mcache. Cuando el área pequeña no tiene suficiente espacio, buscará áreas libres en el mspan señalado por mcache.alloc[tinySpanClass]. Por supuesto, si el espacio de span en mcache también se agota, se activará el proceso de reponer mspan de mcentral a mcache.

Los objetos pequeños se refieren a objetos con un tamaño entre (16B, 32 KB]. Los principios de asignación de dichos objetos son los siguientes:

1. Primero, divida el objeto en una clase abarcada. , todos los elementos de la clase span son del mismo tamaño.

2. Busque mspan en la caché de MC y vea si hay elementos libres. Si los hay, la asignación se realizó correctamente. Si no continúa.

3. Busque el mspan apropiado entre nonempty y emtpy de mcentral.allocSpan[SpanClass] y devuélvalo a mcache. Si no lo encuentra, vaya a mcentral ->;Mheap. alloc() asigna un nuevo mspan a mcentral.

Los objetos grandes se refieren a objetos cuyo tamaño supera los 32 KB. En este momento, mcache y mcentral no se asignarán directamente desde mheap.alloc. () para representar este espacio asignado.

Para la asignación de objetos pequeños comúnmente utilizados en la asignación de programas, Mcache sin bloqueo puede mejorar el rendimiento de la asignación. Cuando no sea suficiente, tome el bloqueo mcentral y luego complete mspan. de mcentral. Los objetos grandes se asignan directamente desde mheap.

En el entorno x8664, el espacio de direcciones virtuales del programa efectivo administrado por golang es esencialmente de solo 48 bits. Hay un miembro pagepagealloc en mheap para administrar el espacio de direcciones. de memoria dinámica de golang Después de que Golang solicite el espacio de direcciones del sistema operativo, marcará el espacio de direcciones como libre o asignado de acuerdo con el uso real. Cuando se asigna a mspan o a un objeto grande, se marca como alloc, y viceversa.

Golang considera que el espacio de direcciones tiene los siguientes cuatro estados:

Golang también define las siguientes operaciones en el espacio de direcciones Función:

En la estructura mheap. es un miembro llamado páginas, que se utiliza para la administración del montón de golang. Su tipo es pageAlloc

Representado por la estructura pageAlloc Todos los espacios de direcciones del montón de golang. :

En el proceso gc de golang, los objetos no utilizados se marcarán como no utilizados, pero los espacios de direcciones utilizados por estos objetos aún no se han devuelto al sistema operativo. La aplicación y la liberación del espacio de direcciones se basan en las páginas de golang. (En realidad dividido). El resultado final del barrido es solo marcar un espacio de direcciones para asignar y en realidad no libera el espacio de direcciones al sistema operativo. La verdadera liberación es el proceso de limpieza que sigue.

Sweep() se usará para intentar liberar un intervalo; después de la marca gc; mheap.alloc también se usará para limpiar con barrido cuando se solicita mspan.

La limpieza de mspan implica principalmente las siguientes funciones

Como se mencionó anteriormente, el barrido solo marca la página como asignable, pero no libera el espacio de direcciones, la verdadera liberación del espacio de direcciones es el proceso de limpieza; .

La limpieza real consiste en pagealloc.scavenge ()->; SysUnused() libera el espacio de direcciones representado por el bloque escaneado para su liberación (use sysUnused() para devolver el espacio de direcciones al sistema operativo).

Golang tiene dos procesos de limpieza: