Saltar al contenido

Asignación de memoria de pila vs montón

septiembre 29, 2021
gfg 200x200 min

La memoria en un programa C / C ++ / Java se puede asignar en una pila o en un montón.
Requisito previo: diseño de memoria del programa C.

Asignación de pila: La asignación ocurre en bloques contiguos de memoria. Lo llamamos una asignación de memoria de pila porque la asignación ocurre en la pila de llamadas de función. El compilador conoce el tamaño de la memoria que se asignará y cada vez que se llama a una función, sus variables obtienen memoria asignada en la pila. Y cada vez que finaliza la llamada a la función, se desasigna la memoria para las variables. Todo esto sucede usando algunas rutinas predefinidas en el compilador. Un programador no tiene que preocuparse por la asignación de memoria y la desasignación de variables de pila. Este tipo de asignación de memoria también se conoce como asignación de memoria temporal porque tan pronto como el método finaliza su ejecución, todos los datos que pertenecen a ese método se eliminan automáticamente de la pila. Significa que se puede acceder a cualquier valor almacenado en el esquema de memoria de la pila siempre que el método no haya completado su ejecución y esté actualmente en estado de ejecución.

Puntos clave:

  • Es un esquema de asignación de memoria temporal donde los miembros de datos son accesibles solo si el método () que los contenía se está ejecutando actualmente.
  • Asigna o desasigna la memoria automáticamente tan pronto como el método correspondiente completa su ejecución.
  • Recibimos el error correspondiente Java. lang. StackOverFlowError por JVM, si la memoria de la pila está llena por completo.
  • La asignación de memoria de pila se considera más segura en comparación con la asignación de memoria de pila porque solo puede acceder el hilo propietario a los datos almacenados.
  • La asignación y desasignación de memoria es más rápida en comparación con la asignación de memoria Heap.
  • La memoria de pila tiene menos espacio de almacenamiento en comparación con la memoria de pila.

CPP

int main()

{

   

   

   int a;

   int b[10];

   int n = 20;

   int c[n];

}

Asignación de montón: La memoria se asigna durante la ejecución de instrucciones escritas por programadores. Tenga en cuenta que el nombre del montón no tiene nada que ver con la estructura de datos del montón. Se llama montón porque es un montón de espacio de memoria disponible para que los programadores lo asignen y desasignen. Cada vez que creamos un objeto, siempre se crea en el espacio de pila y la información de referencia a estos objetos siempre se almacena en la memoria de pila. La asignación de memoria de pila no es tan segura como lo era la asignación de memoria de pila porque los datos almacenados en este espacio son accesibles o visibles para todos los subprocesos. Si un programador no maneja bien esta memoria, puede ocurrir una pérdida de memoria en el programa.

La asignación de memoria Heap se divide en tres categorías: – Estas tres categorías nos ayudan a priorizar los datos (Objetos) que se almacenarán en la memoria Heap o en la recolección de basura.

  • Generación joven – Es la parte de la memoria donde se hacen todos los nuevos datos (objetos) para asignar el espacio y siempre que esta memoria está completamente llena, el resto de los datos se almacena en la recolección de basura.
  • Generación antigua o titular – Esta es la parte de la memoria Heap que contiene los objetos de datos más antiguos que no se usan con frecuencia o que no se usan en absoluto.
  • Generación permanente – Esta es la parte de la memoria Heap que contiene los metadatos de la JVM para las clases en tiempo de ejecución y los métodos de aplicación.

Puntos clave:

  • Recibimos el mensaje de error correspondiente si el espacio del montón está completamente lleno, java. lang.OutOfMemoryError por JVM.
  • Este esquema de asignación de memoria es diferente de la asignación de espacio de pila, aquí no se proporciona una función de desasignación automática. Necesitamos usar un recolector de basura para eliminar los objetos antiguos no utilizados con el fin de usar la memoria de manera eficiente.
  • El tiempo de procesamiento (tiempo de acceso) de esta memoria es bastante lento en comparación con la memoria de pila.
  • La memoria de pila tampoco es segura para subprocesos como la memoria de pila porque los datos almacenados en la memoria de pila son visibles para todos los subprocesos.
  • El tamaño de la memoria de pila es bastante mayor en comparación con la memoria de pila.
  • La memoria de pila es accesible o existe siempre que se ejecute toda la aplicación (o programa Java).

CPP

int main()

{

   

   

   int *ptr  = new int[10];

}

Ejemplo entremezclado de ambos tipos de asignación de memoria Heap y Stack en Java:

Java

class Emp {

    int id;

    String emp_name;

    public Emp(int id, String emp_name) {

        this.id = id;

        this.emp_name = emp_name;

    }

}

public class Emp_detail {

    private static Emp Emp_detail(int id, String emp_name) {

        return new Emp(id, emp_name);

    }

    public static void main(String[] args) {

        int id = 21;

        String name = "Maddy";

        Emp person_ = null;

        person_ = Emp_detail(id, emp_name);

    }

}

A continuación se muestran las conclusiones a las que llegaremos tras analizar el ejemplo anterior:

  • Cuando comenzamos la ejecución del programa have, todas las clases de tiempo de ejecución se almacenan en el espacio de memoria Heap.
  • Luego encontramos el método main () en la siguiente línea que se almacena en la pila junto con todo su primitivo (o local) y la variable de referencia Emp de tipo Emp_detail también se almacenará en la pila y señalará el objeto correspondiente. almacenado en la memoria del montón.
  • Luego, la siguiente línea llamará al constructor parametrizado Emp (int, String) desde main () y también se asignará a la parte superior del mismo bloque de memoria de pila. Esto almacenará:
    • La referencia de objeto del objeto invocado de la memoria de pila.
    • El valor primitivo (tipo de datos primitivo) int id en la memoria de pila.
    • La variable de referencia del argumento String emp_name que apuntará a la cadena real del grupo de cadenas a la memoria del montón.
  • Luego, el método principal volverá a llamar al método estático Emp_detail (), para el cual la asignación se realizará en el bloque de memoria de la pila encima del bloque de memoria anterior.
  • Por lo tanto, para el objeto Emp recién creado de tipo Emp_detail y todas las variables de instancia se almacenarán en la memoria del montón.

Representación pictórica como se muestra en la Figura 1 a continuación:

Untitled4

Figura 1

Diferencias clave entre asignaciones de pila y montón

  1. En una pila, el compilador realiza automáticamente la asignación y la desasignación, mientras que en el montón, el programador debe realizarla manualmente.
  2. El manejo del marco de pila es más costoso que el manejo del marco de pila.
  3. Es más probable que el problema de escasez de memoria ocurra en la pila, mientras que el problema principal en la memoria del montón es la fragmentación.
  4. El acceso a la trama de pila es más fácil que la trama de pila, ya que la pila tiene una pequeña región de memoria y es compatible con el caché, pero en el caso de las tramas de pila que se encuentran dispersas por la memoria, causa más fallas de caché.
  5. Una pila no es flexible, el tamaño de la memoria asignada no se puede cambiar, mientras que un montón es flexible y la memoria asignada se puede modificar.
  6. El tiempo de acceso a las tomas de pila es más que una pila.

Gráfica comparativa

Parámetro APILAR MONTÓN
Básico La memoria se asigna en un bloque contiguo. La memoria se asigna en cualquier orden aleatorio.
Asignación y desasignación Automático por instrucciones del compilador. Manual del programador.
Costo Menos Más
Implementación Fácil Duro
Tiempo de acceso Más rápido Más lento
Tema principal Escasez de memoria Fragmentación de la memoria
Localidad de referencia Excelente Adecuado
La seguridad Seguro para subprocesos, solo el propietario puede acceder a los datos almacenados No es seguro para subprocesos, los datos almacenados son visibles para todos los subprocesos
Flexibilidad Tamaño fijo Cambiar el tamaño es posible
Estructura del tipo de datos Lineal Jerárquico

close