Asignación de memoria de pila frente a pila

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 de la pila automáticamente. Medio,

Puntos clave:

  • Es un esquema de asignación de memoria temporal en el que se puede acceder a los miembros de datos 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 correspondiente error Java. idioma StackOverFlowError por JVM, si la memoria de la pila se 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 el subproceso del propietario puede acceder 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 en montón.
  • Stack-memory tiene menos espacio de almacenamiento en comparación con Heap-memory.

CPP

int main()
{
   // All these variables get memory
   // allocated on stack
   int a;
   int b[10];
   int n = 20;
   int c[n];
}

Asignación de almacenamiento dinámico: la memoria se asigna durante la ejecución de las instrucciones escritas por los programadores. Tenga en cuenta que el montón de nombres no tiene nada que ver con la estructura de datos del montón. Se llama montón porque es una pila de espacio de memoria disponible para que los programadores asignen y desasignen. Cada vez que creamos un objeto, siempre se crea en Heap-space y la información de referencia a estos objetos siempre se almacena en Stack-memory. 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 fuga de memoria en el programa.

La asignación de memoria Heap se divide además 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 crean todos los datos nuevos (objetos) para asignar el espacio y cada vez que esta memoria se llena por completo, el resto de los datos se almacena en la recolección de basura.
  • Generación antigua o permanente: esta es la parte de la memoria dinámica 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 de almacenamiento dinámico que contiene los metadatos de JVM para las clases de tiempo de ejecución y los métodos de aplicación.

Puntos clave:

  • Recibimos el mensaje de error correspondiente si Heap-space 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 para 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 Stack.
  • Heap-memory tampoco es seguro para subprocesos como Stack-memory porque los datos almacenados en Heap-memory son visibles para todos los subprocesos.
  • El tamaño de la memoria Heap es bastante mayor en comparación con la memoria Stack.
  • Se puede acceder a la memoria del montón o existe siempre que se ejecute toda la aplicación (o el programa Java).

CPP

int main()
{
   // This memory for 10 integers
   // is allocated on heap.
   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 presentan las conclusiones a las que llegaremos después de analizar el ejemplo anterior:

  • A medida que 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 lo 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 Heap.
  • 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 string real del grupo de strings en 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 sobre el 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:

Figura 1

Diferencias clave entre las 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 hacerlo manualmente.
  2. El manejo del marco Heap es más costoso que el manejo del marco stack.
  3. Es más probable que ocurra un problema de escasez de memoria en la pila, mientras que el problema principal en la memoria del montón es la fragmentación.
  4. El acceso a los marcos de pila es más fácil que el marco de pila, ya que la pila tiene una pequeña región de memoria y es compatible con la caché, pero en el caso de tramas de pila que están dispersas por toda la memoria, provoca más errores 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. Acceder al tiempo de las tomas del montón es más que una pila.

Cuadro comparativo

Parámetro PILA 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 por el programador.
Costo Menos Más
Implementación Fácil Difícil
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
Privilegiado Se prefiere la asignación de memoria estática en la array. Se prefiere la asignación de memoria en montón en la lista vinculada.
Tamaño Pequeño que la memoria del montón. Más grande que la memoria de pila.

Publicación traducida automáticamente

Artículo escrito por Ankit_Bisht y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *