[iOS] Cinco áreas principales de la gestión de la memoria

Blog de referencia: Aprendizaje sobre administración de memoria de iOS, parte 1: cinco áreas de memoria
3.1 OC presenta cinco áreas de memoria

1. Breve descripción

Para que se ejecute un programa, el primer paso es cargarlo en la memoria. Hay
cinco áreas principales de la memoria: área de pila, área de montón, área estática, área constante y segmento de código.

  1. El compilador asigna y libera automáticamente el área de la pila (pila) para almacenar valores de parámetros de funciones, variables locales, etc. La pila es una estructura de datos del sistema y es exclusiva del subproceso/proceso. El área de pila del iPhone es de solo 512K y su método de operación es similar al de la pila en la estructura de datos.
    Ventajas: rápido y eficiente
    . Desventajas: limitado, datos inflexibles [primero en entrar, último en salir]
  2. El programador asigna y libera el área del montón (montón). Si el programador no la libera, el sistema operativo puede reclamarla una vez finalizado el programa. Similar a una lista vinculada
    Ventajas: flexible y conveniente, amplia gama de adaptabilidad de datos
    Desventajas: la eficiencia se reduce hasta cierto punto
  3. El sistema libera el área estática, el área de almacenamiento para variables globales y variables estáticas, una vez finalizado el programa.
  4. El área constante almacena cadenas constantes y el sistema la libera una vez finalizado el programa.
  5. El área de código almacena el código binario de la función y el sistema lo libera una vez finalizado el programa.

2. Área de montón y área de pila

int main(int argc, const char * argv[]) {
    
    
 
    // 局部变量是保存在栈区的
    // 栈区变量出了作用域之后,就会被销毁
    NSInteger i = 10;
 
    NSLog(@"%zd", i);
 
    // 赋值语句右侧,使用 new\alloc\init 方法创建的对象是保存在堆区的
    // xinge 变量中,记录的是堆区的地址
    // 在 OC 中,有一个内存管理机制,叫做 `ARC`,可以自动管理 OC 代码创建对象的生命周期
    // 因此,在开发 OC 程序的时候,程序员通常不需要考虑内存释放的工作
    LJXPerson *xinge = [LJXPerson new];
    NSLog(@"%@", xinge);
    return 0;
}

2.1 Área de pila

Área de pila (pila [stæk]): asignada y liberada automáticamente por el compilador

2.1.1 Guardar en el área de pila (responsabilidad del área de pila/contenido almacenado)

  • variables locales
  • Parámetros reales del método (por ejemplo: en la función principal, llamando al método, parámetros reales en el método)

2.1.2 Características del área de la pila

  • El espacio de almacenamiento es limitado. El tamaño de pila del iPhone es de sólo 512k (predeterminado), lo cual es muy limitado.
  • Continuidad: Las direcciones del área de la pila son continuas.
  • Las direcciones se asignan de mayor a menor y las direcciones del área de pila se organizan de mayor a menor según el orden de asignación.
  • La velocidad de acceso es rápida.
  • Gestión del sistema (la memoria en el área de la pila es gestionada por el sistema)

2.1.3 Otros

Si se llama a un método en un programa, se abrirá un "marco de pila" (este marco de pila puede entenderse como un área continua) La
dirección del marco de pila no es continua con la dirección de la variable local anterior. La dirección del parámetro se registra en el marco de la pila
y las variables locales dentro de los métodos. Después de ejecutar el método, el marco de la pila se destruye (se saca de la pila)
<<<De esta manera, después de cada ejecución, la pila se saca para liberar la memoria. Esto siempre garantizará que la memoria ocupada por el área de la pila no sea particularmente grande >>
palabras tan extracurriculares-> Cuando estamos desarrollando, si cada método está escrito muy breve y las variables declaradas por cada método son muy pocas,
esto definitivamente ahorrará memoria.

Resumir

Cómo funciona el área de la pila al llamar a métodos

  • Marco de pila abierto
  • Guardar parámetros reales
  • Guardar variables locales
  • Una vez completado el método, se extrae la pila, se destruye el marco de la pila y se libera el espacio.

2.2 área del montón

Área de montón (montón [hiːp]): asignado y liberado por el programador. Si el programador no lo libera, se producirán pérdidas de memoria.

2.2.1 Guardar en el área del montón:

  • Los objetos creados usando el nuevo método \alloc\init se almacenan en el área del montón
  • Todas las variables miembro del objeto creado se almacenan en el área del montón

Al desarrollar programas OC, los programadores generalmente no necesitan considerar el trabajo de liberación de memoria.
Pero si está en el código OC, si utiliza la función del lenguaje C para asignar espacio, debe considerar liberar la memoria.

  1. El tamaño del área del montón lo determina el sistema, incluido: memoria del sistema/espacio de intercambio en disco...
  2. Utilizado por el sistema 链表para administrar la asignación de memoria en el área del montón
  3. { El programador solo necesita ser responsable de asignar y liberar memoria en el área del montón }

2.2.2 Características del área del montón

  • Compartido por todos los programas.
  • Almacenar grandes datos
  • Gestión del programador: los programadores deben administrar la memoria en el área del montón
  • Discontinuo: las direcciones del área del montón son discontinuas
  • La velocidad no es tan rápida como la del área de la pila: La velocidad de acceso al área del montón no es tan rápida como la del área de la pila, porque si queremos acceder a las propiedades de los objetos creados en el área del montón, primero debemos encontrar la dirección de el área de la pila a través de variables, y luego usar la dirección para ubicar una determinada ubicación en el área del montón. Una ubicación. Solo después de encontrar esta ubicación podemos acceder al valor correspondiente al atributo almacenado en este objeto. Debido al proceso de búsqueda En esta dirección, la velocidad no es tan rápida como la del área de pila.

3. Variables globales, variables estáticas y constantes

3.1 Área de memoria donde se guardan variables globales/variables estáticas/constantes

El desarrollo debe mantener los cambios dentro de un alcance limitado.

3.1.1 Área de memoria donde se guardan las variables globales/variables estáticas

Esta sección varía según el compilador, el sistema operativo y la plataforma específica. Algunos compiladores y plataformas pueden tener sus propias estrategias de optimización para el diseño de la memoria y el uso de segmentos. Por lo tanto, los detalles pueden variar y deberá consultar la documentación de su compilador y plataforma para obtener más detalles.

En Xcode13.3.1, las variables globales no inicializadas y las variables estáticas se almacenan en el área estática (sección .BSS), y las variables globales inicializadas y las variables estáticas se almacenan en el área de datos (sección .data).
Cabe señalar que el segmento de datos generalmente se refiere a una subárea del área estática. Estos términos pueden definirse y usarse de manera diferente en diferentes sistemas y compiladores. A veces, los términos segmento de datos y área estática también se utilizan para referirse a la misma área de memoria.

verificar:

Código de verificación:

// 设置两个全局变量,一个初始化,一个不初始化
int num1 = 1;
int num2;

int main(){
    
    
    @autoreleasepool {
    
    
        NSLog(@"num1 pointer = %p", &num1);
        NSLog(@"num2 pointer = %p", &num2);
        
        // 初始化num2
        num2 = 2;
        NSLog(@"init num2 pointer = %p", &num2);
        
        // 设置两个静态变量,一个初始化,一个不初始化
        static int sNum1 = 1;
        static int sNum2;
        
        NSLog(@"sNum1 pointer = %p", &sNum1);
        NSLog(@"sNum2 pointer = %p", &sNum2);
        
        sNum2 = 2;
        NSLog(@"init sNum2 pointer = %p", &sNum2);
    }
}

Resultados de la validación:

Insertar descripción de la imagen aquí

Se puede saber:

  1. Las variables estáticas y las variables globales no se inicializan ni almacenan en el área estática (sección .BSS), con direcciones consecutivas;
  2. Las variables estáticas y las variables globales se inicializan y almacenan en el área de datos (sección .data) con direcciones consecutivas;
  3. Las direcciones de almacenamiento de las variables estáticas y las variables globales permanecen sin cambios antes y después de la inicialización, lo que indica que sus áreas de almacenamiento se determinan al principio y no cambiarán posteriormente;
  4. Las direcciones del área estática (segmento .BSS) y el área de datos (segmento .data) son continuas y su división no es estricta (la división debe ser dinámica) y pueden considerarse como un área.

3.1.2 Área de memoria donde se guardan las constantes

Las constantes se almacenan en el área de constantes.

Agregue una constante al código de verificación anterior:

// 设置两个全局变量,一个初始化,一个不初始化
int num1 = 1;
int num2;

int main(){
    
    
    @autoreleasepool {
    
    
        NSLog(@"num1 pointer = %p", &num1);
        NSLog(@"num2 pointer = %p", &num2);
        
        // 初始化num2
        num2 = 2;
        NSLog(@"init num2 pointer = %p", &num2);
        
        // 设置两个静态变量,一个初始化,一个不初始化
        static int sNum1 = 1;
        static int sNum2;
        
        NSLog(@"sNum1 pointer = %p", &sNum1);
        NSLog(@"sNum2 pointer = %p", &sNum2);
        
        sNum2 = 2;
        NSLog(@"init sNum2 pointer = %p", &sNum2);
        
        // 常量
        const int cNum = 3;
        NSLog(@"cNum pointer = %p", &cNum);
    }
}

resultado:
Insertar descripción de la imagen aquí

Se puede saber:

  1. Las constantes, las variables estáticas y las variables globales no se almacenan en la misma área, sino que las constantes se almacenan en el área de constantes.

3.2 Área estática

Para almacenar variables estáticas y variables globales, si se inicializan al principio determina si se almacenan en el segmento .BSS o en el segmento .data. Una vez decidido, no se cambiarán.

3.3 Área constante

Almacene constantes, ya sea que estén inicializadas o no.

4. Puntero etiquetado

Los siguientes son los planes realizados por tres sistemas para optimizar la gestión de la memoria.
Insertar descripción de la imagen aquí

El primero es el TaggedPointer del que estamos hablando, te recomendamos ver el vídeo oficial de la WWDC 2020, que explica en detalle por qué se utiliza TaggedPointer, para resumir los siguientes puntos

  1. Especialmente utilizado para almacenar datos pequeños, determine directamente el tipo de datos a través de bits altos, como NSNumber, NSDate, NSTaggedPointerString string
  2. El objeto pequeño no ingresa al área del montón. El valor se almacena directamente en el puntero, en lugar de pensar en datos normales. El puntero almacena la dirección, por lo que en realidad no es un objeto, solo una variable ordinaria. No existe. en el montón y, naturalmente, no hay necesidad de malloc y free.
  3. La lectura de la memoria es 3 veces más eficiente y la velocidad de creación es 106 veces más rápida

Este es el alcance aproximado del uso de TaggedPointer, como se muestra en la figura
Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/m0_63852285/article/details/131735271
Recomendado
Clasificación