Error de memoria del montón de Java

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderá a utilizar de manera efectiva la memoria del montón de Java para evitar el error de memoria del montón de Java.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/DataStructuresGroup -.-> java/arrays("Arrays") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("Exceptions") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/SystemandDataProcessingGroup -.-> java/system_methods("System Methods") subgraph Lab Skills java/arrays -.-> lab-117690{{"Error de memoria del montón de Java"}} java/classes_objects -.-> lab-117690{{"Error de memoria del montón de Java"}} java/exceptions -.-> lab-117690{{"Error de memoria del montón de Java"}} java/arraylist -.-> lab-117690{{"Error de memoria del montón de Java"}} java/system_methods -.-> lab-117690{{"Error de memoria del montón de Java"}} end

Error de memoria del montón de Java

El Error de memoria del montón de Java se produce cuando la Máquina Virtual de Java (JVM) se queda sin memoria mientras asigna objetos a la memoria del montón de Java. Malas prácticas de programación, fugas de memoria, bibliotecas de terceros pueden todos dar lugar a este error.

Código:

import java.util.ArrayList;

public class JavaHeapMemoryError {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        while (true) {
            Object o = new Object();
            list.add(o);
        }
    }
}

Para ver el error en acción, compile y ejecute el código en la terminal:

javac JavaHeapMemoryError.java
java -Xmx512m JavaHeapMemoryError

El programa intenta asignar la mayor cantidad de memoria posible creando continuamente objetos y agregándolos a la ArrayList hasta que la JVM lance el OutOfMemoryError. El parámetro -Xmx establece la memoria del montón máxima asignada a la JVM.

Causas del Error de Memoria del Montón de Java

El Error de Memoria del Montón de Java se produce principalmente debido a malas prácticas de programación, fugas de memoria y bibliotecas de terceros. Para evitarlo, debemos evitar los bucles infinitos, los objetos no utilizados que se mantengan demasiado tiempo sin ser limpiados y hacer que los objetos no utilizados estén disponibles para el recolector de basura.

Código:

public class JavaHeapMemoryError {
    public static void main(String[] args) {
        int[] arr = new int[100000000];
        for(int i=0; i<arr.length; i++){
            arr[i] = i;
        }
        System.out.println("Memory allocated");
    }
}

Para ver el código en acción, compile y ejecute el código en la terminal:

javac JavaHeapMemoryError.java
java -Xmx256m JavaHeapMemoryError

Fuga de memoria

La fuga de memoria se produce cuando un objeto no utilizado en la memoria del montón todavía tiene referencias válidas y no puede ser eliminado por el recolector de basura. Para evitar las fugas de memoria, todos los recursos abiertos deben ser cerrados utilizando el bloque finally.

Código:

public class MemoryLeak {
    static ArrayList<String> arrList = new ArrayList<String>(500);
    public static void main(String args[]) {
        for (int i = 0; i < 500; i++) {
            arrList.add("Element " + i);
        }
        arrList = null;
    }
}

Para ver el código en acción, compile y ejecute el código en la terminal:

javac MemoryLeak.java
java -Xmx256m MemoryLeak

Uso excesivo de finalizadores

El uso excesivo de finalizadores puede conducir al Error de Memoria del Montón de Java porque las clases que contienen un método finalize no tienen sus espacios de objetos reclaimados durante la recolección de basura.

Código:

public class ExcessiveFinalizer {
    public void finalize() {
        //Realizar alguna limpieza
    }

    public static void main(String[] args) {
        ArrayList<ExcessiveFinalizer> list = new ArrayList<ExcessiveFinalizer>();
        while (true) {
            list.add(new ExcessiveFinalizer());
        }
    }
}

Para ver el código en acción, compile y ejecute el código en la terminal:

javac ExcessiveFinalizer.java
java -Xmx256m ExcessiveFinalizer

Aumentar la memoria del montón

Si el error se causó por una memoria insuficiente asignada a la JVM, podemos aumentar el espacio de montón disponible para ella aumentando el límite establecido por el comando -Xmx.

Código:

public class IncreaseHeapMemory {
    public static void main(String[] args) {
        Integer[] outOfMemoryArray = new Integer[Integer.MAX_VALUE];
    }
}

Para ver el código en acción, compile y ejecute el código en la terminal:

javac IncreaseHeapMemory.java
java -Xmx8g IncreaseHeapMemory

Resumen

En este laboratorio, has aprendido cómo administrar efectivamente la memoria del montón para tus aplicaciones Java y evitar los errores de memoria del montón de Java. Exploramos diferentes técnicas para prevenir el error, como evitar bucles ineficientes, cerrar recursos no utilizados y hacer que los objetos no utilizados estén disponibles para el recolector de basura temprano. Finalmente, si la memoria del montón insuficiente fue la causa del error, aumentamos el límite utilizando el comando -Xmx.