Errores de memoria de montón y pila en Java

La asignación de memoria en Java es administrada por la máquina virtual Java en Java. Divide la memoria en memoria de pila y montón, que se muestra a continuación en los siguientes medios de la siguiente manera:

Apilar memoria en Java 

Es la asignación de memoria temporal donde las variables locales, las variables de referencia se asignan a la memoria cuando se llama a sus métodos. Contiene referencias al objeto que se almacenan en un montón. Después de la ejecución del método, se borra la memoria que contiene esas variables. Podemos acceder a esta memoria en orden Last In First Out. La asignación y la desasignación son más rápidas que la memoria del montón. Es más seguro ya que solo el propietario del hilo puede acceder a los datos. Si la memoria de pila está llena, la JVM lanza StackOverflowException .

Ilustración:

// Java Program to Illustrate Stack Memory  

// Importing required I/O classes 
import java.io.*;

// Main class 
class GFG {

    // Main driver method 
    public static void main (String[] args) {

        // Creating an integer array 
        int a [] = new int[5];  
    }
}

Explicación esquemática del ejemplo anterior

En la ilustración anterior, podemos percibir de manera concluyente los medios anteriores que se muestran y concluir los siguientes puntos

  • ‘a’ es una variable de tipo array almacenada en una pila.
  • La nueva palabra clave se usa para asignar memoria en el montón.
  • 5 es el tamaño de la array.

Error de memoria de pila

Cada vez que llamamos a un método, después de su ejecución sale de la memoria de la pila. Si sus métodos permanecen en la pila, entonces la pila estará llena. Si la pila está llena, no podemos empujar, si lo hacemos, obtendremos el error java.lang.StackOverflowError que será lanzado por JVM. Se lanza cuando llamas a un método y no queda espacio en la pila. En la mayoría de los casos, se lanza cuando llamamos a un método recursivamente sin ninguna condición de terminación adecuada. Podemos evitarlo asegurándonos de que los métodos se ejecuten con la terminación adecuada.

Después de cierto punto, la pila estará llena 

Tomemos un ejemplo de ejemplo de cálculo factorial de un número para ilustrar lo mismo.

Java

// Java Program to Illustrate Stack Memory Error
// Factorial function without termination condition
// will cause StackOverflow error
 
// Importing I/O classes
import java.io.*;
 
// Main class
class GFG {
 
    // Main driver method
    public static void main (String[] args) {
 
        // Declaring a custom number whose factorial is to be computed
        int n = 5;
 
        // Print and display the factorial
        System.out.println(factorial(n));
    }
 
    // Method
    // To calculate factorial
    static int factorial(int n) {
 
        // Note: There is no termination condition
 
        // Calling recursively to compute factorial of a number
        return n * factorial(n - 1);
    }
}

Producción: 

Nota: si ejecuta este código, obtendrá java.lang.StackOverflowError. Podemos evitarlo agregando la condición de terminación adecuada si agregamos la condición de terminación en la función factorial antes de la declaración de devolución. Debajo de la condición de terminación, elimine el error de la siguiente manera:

si (n==0)

devolver 0;

Memoria de montón en Java 

La memoria del montón en Java se utiliza para asignar memoria a los objetos y clases JRE (Java Runtime Environment). Cuando se crea un objeto, siempre se crea en el montón y la referencia al objeto se almacena en la memoria de la pila. No es seguro como pila porque se puede acceder a él globalmente. El acceso a esta memoria es relativamente más lento que la memoria de pila. Necesita un recolector de basura para eliminar los objetos no utilizados. Si el montón está lleno, JVM genera java.lang.OutOfMemoryError . No es seguro para subprocesos como una pila.

Ejemplo 

Java

// Java Program to Illustrate Execution in Heap Memory
 
// Importing input output classes
import java.io.*;
 
// Main class
class GFG {
 
    // Static class
    static class Student {
 
        int roll_no;
 
        // The reference variable of String argument name
        // which points to the actual string from string
        // pool in heap memory
        String name;
 
        // Constructor of this static class
        Student(int roll_no, String name)
        {
 
            // This keyword refers to current instance
            this.roll_no = roll_no;
            this.name = name;
        }
    }
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Primitive roll no value directly stored in stack
        // memory
        int roll_no = 1;
        // Primitive name value directly stored in stack
        // memory
        String name = "Jack";
 
        // Creating reference variable of Student class type
        // created in a stack memory which will point to
        // the object in heap memory
        // New object created in heap memory
        Student st = new Student(roll_no, name);
 
        // Print and display the student name and roll
        // number
        System.out.println("Student name -> " + st.name);
        System.out.println("Student roll no. -> "
                           + st.roll_no);
    }
}
Producción

Student name -> Jack
Student roll no. -> 1

Error de memoria en montón

También ahora es adecuado discutir los errores de memoria en montón en Java. Entonces, ocurre cuando creamos muchos objetos nuevos en la memoria del montón y no queda espacio para los nuevos objetos, entonces JVM arrojará java.lang.OutOfMemoryError . El recolector de basura eliminó los objetos que no tienen referencias, pero no puede eliminar los objetos que tienen una referencia. Se puede evitar eliminando referencias a objetos no deseados.

Ejemplo: 

Java

// Java Program to Illustrate OutOfMemoryError
// in Heap Space
 
// Importing input output classes
import java.io.*;
 
// Main class
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an array whose size is havoc
        Long a[] = new Long[100000 * 10000];
    }
}

Producción:

Explicación de salida: en el ejemplo anterior, se intenta inicializar la array larga con un tamaño muy grande y el almacenamiento dinámico de Java no es suficiente para asignar esta array, genera un java.lang.OutOfMemoryError en el espacio de almacenamiento dinámico de Java.

Publicación traducida automáticamente

Artículo escrito por iramkhalid24 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 *