Glibc memory management

  

El diseño de la memoria del proceso LINUX de la plataforma X86 es el siguiente:

El significado del párrafo anterior es el siguiente:

texto: almacene el código del programa, compile el tiempo para determinarlo, solo lectura;

datos: almacene datos que se pueden determinar cuando el programa se está ejecutando, legible y con capacidad de escritura;

bss: variables globales y variables estáticas definidas sin inicialización;

heap: generalmente La asignación del programador, si no se libera, puede ser reciclada por el sistema operativo al final del programa;

pila: el compilador asigna automáticamente la versión, almacena los parámetros de la función, las variables locales, etc .;

Mmap: Área del mapa;

Los programas pueden usar las llamadas del sistema para administrar el montón y el mmap directamente, pero más a menudo usan el malloc y el servicio gratuito que proporciona C para asignar dinámicamente y liberar memoria. La limitación de la pila en Linux es aproximadamente 8M, y en Windows es 2M.

Programa de administración de memoria al estilo C:

también es malloc y gratuito, principalmente a través de brk o mmap para agregar más Memoria virtual El uso de malloc para administrar la memoria para los programas que necesitan mantener el almacenamiento a largo plazo puede ser muy decepcionante. Si hay un gran número de referencias de memoria no fijadas, a menudo es difícil saber cómo se liberan.

Administración de memoria agrupada:

Las aplicaciones pueden administrar la memoria más fácilmente, la asignación de memoria y la recuperación son más rápidas, las agrupaciones de manejo de errores pueden asignarse previamente para que los programas aún se agoten cuando se agota la memoria regular Se puede restaurar, hay una implementación estándar que es muy fácil de usar.

El grupo de memoria solo es adecuado para operaciones que se pueden organizar, por lo general no funciona bien con bibliotecas de terceros, si la estructura del programa cambia, debe modificar el grupo de memoria, debe recordar qué grupo debe realizar. Asignación.

Reference Count:

No se olvide de llamar a la función de conteo de referencia, no se puede liberar como parte de una estructura de datos en bucle, es más difícil y más lento en un entorno multiproceso.

Recolección de basura:

Nunca se preocupe por el doble lanzamiento de la memoria o el ciclo de vida de un objeto;

no puede interferir cuando se libera la memoria; puede administrarse más lentamente que otras formas. Si olvida establecer el puntero que ya no se usa en nulo,

Objetivos de diseño del Administrador de memoria:

Maximizar compatibilidad;

Maximizar la portabilidad (puede Una buena comunicación con el sistema operativo);

desperdició el espacio más pequeño (la administración de su propia estructura de datos también requiere memoria, también es necesario prestar atención a la fragmentación);

la velocidad más rápida ( Principio 2/8, utilizado principalmente para optimizar hotspots);

Maximiza la capacidad de ajuste (puede adaptarse a múltiples necesidades de distribución, o se adapta por configuración);

Maximiza la localidad (La consideración aquí es la relación entre la memoria caché de la CPU y la memoria);

Maximice las funciones de depuración (no es necesario que sea un programador);

Maximice la adaptabilidad (sin modificaciones) Adaptabilidad al configurar);

ptmalloc implementa malloc y free Y una serie de otras funciones para proporcionar apoyo a la gestión de memoria dinámica. El asignador se encuentra entre el programa de usuario y el kernel y se utiliza para responder a la solicitud de asignación del usuario, solicitar memoria del sistema operativo y luego devolverla al programa de usuario. Con el fin de mantener una asignación eficiente, el asignador generalmente asigna previamente una gran parte de la memoria y la administra mediante algún algoritmo. La memoria que el usuario libera no se devuelve inmediatamente al sistema operativo. En el momento del diseño, ptmalloc comprometió objetivos de diseño tales como alta eficiencia, alta utilización del espacio y alta disponibilidad. Los supuestos de diseño son los siguientes:

Use mmap para asignar memoria grande para ciclos de vida largos;

La asignación de memoria muy grande siempre usa mmap;

Asignación de memoria para ciclos de vida cortos Use brk;

Intente almacenar en caché solo la memoria pequeña y temporal, y la memoria grande se devuelve directamente al sistema;

Los bloques de memoria pequeños solo se fusionan cuando están en malloc y libres; Br>

La condición para reducir el almacenamiento dinámico es que el tamaño libre actual más el tamaño de los trozos que se pueden combinar antes y después es mayor que 64K, y el tamaño de la parte superior del montón alcanza el umbral;

Los programas que requieren almacenamiento a largo plazo no son adecuados Ptmalloc;

La estructura general es la siguiente:

Los datos reales son Chunk, la estructura del Chunk en uso es la siguiente:

Donde:

P: indica si el Chunk anterior está en uso;

M: El Chunk de bandera es la memoria virtual obtenida de esa área de memoria;

A: Si la bandera es el área de asignación primaria;

La estructura del fragmento libre en la memoria es la siguiente:

Use bin para administrar el vacío en glibc Pedazos libres, los detalles no se mencionan. Cuando el fragmento libre está vinculado al contenedor, ptmalloc verificará si los fragmentos anteriores y posteriores también lo son. Si es así, se fusionará en una estructura grande de chunk.bin como sigue:

ptmalloc Aumente la velocidad de la asignación, primero pondrá algunos fragmentos pequeños en los contenedores Rápidos. Los trozos en bandejas rápidas no cambian su indicador de uso P, por lo que no pueden fusionarse. Cuando el usuario asigna una pequeña memoria, ptmalloc primero encontrará el bloque libre de la respuesta en las bandejas rápidas y luego buscará las bandejas sin clasificar. Los trozos libres. Los trozos combinados, o los que no se pueden colocar en los contenedores rápidos, se colocan primero en el contenedor Sin clasificar. Si no se cumplen los requisitos en el contenedor Sin clasificar al momento de la asignación, se agregarán los fragmentos en el contenedor Sin clasificar. En los contenedores.

Debido a que la asignación de dirección baja a alta se usa cuando se asigna memoria, es probable que una memoria grande asignada (que se usa para simular un subcolar) tenga una memoria libre. Es decir, la parte superior. La parte superior se considera después de las ubicaciones rápidas, por lo que este intervalo no está en la estructura de las ubicaciones. Si ptmalloc logra asignar un espacio en la parte superior y la parte superior no es lo suficientemente grande, entonces se reasigna un nuevo subcolar y la parte superior se migra al nuevo sub-montón. El nuevo sub-montón está conectado al sub-montón existente con una lista enlazada individualmente. De la siguiente manera:

Cuando el espacio a asignar sea lo suficientemente grande, ptmalloc usará mmap para asignar directamente la memoria al espacio de proceso usando la asignación de memoria. La porción así asignada estará directamente en contacto con el mapa cuando esté libre, y una referencia a dicha región de memoria causará un error de segmentación.

El último fragmento restante es otro fragmento especial. Si asigna un pequeño fragmento, si no puede encontrar un fragmento adecuado en los contenedores pequeños, si el tamaño del último resto es mayor que el tamaño del fragmento pequeño requerido. . Luego se dividirá en dos, uno para el usuario y el otro para el último fragmento del último resto.

La respuesta de ptmalloc a la solicitud de asignación de memoria del usuario:

Obtenga la información principal El bloqueo del área de asignación, si falla, encuentra el área de asignación no primaria y luego crea una nueva área de asignación no primaria;

Convierte el tamaño de la solicitud del usuario al tamaño del espacio de porción que debe asignarse;

Si chunk_size < = max_fast luego va a 4, de lo contrario, salta 5;

Intenta asignar en contenedores rápidos, si tiene éxito, finalizará;

Si chunk_size < = 512B Un paso, de lo contrario, salte 6;

Encuentre las pequeñas bandejas correspondientes, si se encuentra, la asignación es exitosa; de lo contrario, transfiera 7;

fusione los trozos en las bandejas rápidas, atraviese la porción en la casilla sin clasificar, si Solo hay una porción, y esta porción se ha utilizado en la última asignación, y el tamaño de la porción que se asignará pertenece a los smallbins, y el tamaño de la porción cumple con los requisitos, entonces la porción se corta directamente y la asignación finaliza; de lo contrario, se coloca Contenedores;

at Busque en grandes contenedores; si no puede pasar a 9;

Si el fragmento superior satisface los requisitos, asigne un bloque, de lo contrario, cambie a 10;

Si es el área de asignación principal, llame a sbrk para aumentar el segmento superior Tamaño; de lo contrario, asigne un nuevo sub-montón, o use directamente mmap para asignar; si necesita usar mmap para asignar el turno 11, de lo contrario, gire 12;

use la llamada al sistema mmap para asignar un espacio para el espacio de memoria del programa. Devuelva el puntero al programa de usuario;

Determine si se llama al malloc por primera vez y si es el área de asignación principal, realice una inicialización. De lo contrario, se asigna de acuerdo con las reglas de 10.

Para evitar el aumento de memoria de Glibc, debe prestar atención a los siguientes puntos:

La memoria asignada se libera primero (consideración de la parte superior);

no es adecuado para Administre la memoria de larga duración, especialmente la asignación persistente e irregular y libere la memoria de larga duración;

No desactive el mecanismo de ajuste dinámico del umbral de asignación mmap de ptmalloc;

Ejecución en etapas de múltiples subprocesos Los programas no son adecuados para usar ptmalloc (más adecuado para usar grupos de memoria);

Minimice el número de subprocesos en el programa y evite la asignación y liberación frecuentes de memoria;

Copyright © Conocimiento de Windows All Rights Reserved