Jvm Memory Management

Jvm memory management

Java Memory Management

En Java, la gestión de memoria es el proceso de asignación y desasignación de objetos, conocido como gestión de memoria. Java realiza la gestión de memoria de forma automática. Java utiliza un sistema automático de gestión de memoria llamado recolector de basura (garbage collector). Por lo tanto, no es necesario implementar lógica de gestión de memoria en nuestra aplicación. La gestión de memoria en Java se divide en dos partes principales.

JVM Memory Structure

Heap :

En Java, la heap es una región del espacio de memoria de la computadora donde se almacenan los objetos. Se instancia durante el inicio de la Máquina Virtual y se asigna a la memoria para todas las instancias de clases y matrices. La heap puede tener un tamaño fijo o dinámico dependiendo de la configuración del sistema. Cuando se crea un objeto este se almacena en la memoria heap, y dentro del stack se almacena el nombre del objeto y en vez de guardarse el valor se guarda una referencia (suele ser hexadecimal) a dicho objeto para la memoria heap.

Stack: La memoria de la pila se refiere a una región de la memoria utilizada para almacenar variables locales y gestionar las invocaciones de métodos. Cada hilo en un programa Java tiene su propia pila y opera de manera independiente de la memoria de la heap.

Algunos puntos clave sobre la memoria de la pila en Java son:

Variables Locales: La pila se utiliza para almacenar variables locales e información de llamadas a métodos. Cuando se invoca un método, se empuja un nuevo marco en la pila, y este marco contiene espacio para variables locales, la dirección de retorno y otra información relacionada con la ejecución del método.

LIFO (Last-In-First-Out): La pila sigue una estructura Last-In-First-Out (LIFO), lo que significa que el último método que se llamó es el primero en finalizar, y su marco se elimina de la pila.

Específico del Hilo: Cada hilo en una aplicación Java tiene su propia pila. Esto asegura que cada hilo tenga su propio conjunto de variables locales e información de llamadas a métodos, haciendo que los hilos sean independientes entre sí en términos de ejecución de métodos.

Gestión de Memoria: La memoria asignada para la pila suele ser más pequeña en comparación con la heap. La memoria de la pila se gestiona automáticamente por la Máquina Virtual de Java (JVM) y suele ser más rápida para asignar y desasignar en comparación con la memoria de la heap.

Duración Limitada: La duración de los objetos en la pila está vinculada a la invocación del método. Las variables locales se crean cuando se llama a un método y se destruyen cuando el método se completa.

Sin Recolección de Basura: A diferencia de la heap, la memoria de la pila no está sujeta a la recolección de basura. Una vez que se completa la ejecución de un método, su marco de pila se elimina simplemente de la pila y se recupera la memoria.

Área de Método: El Área de Método, también conocida como PermGen (Generación Permanente) antes de Java 8, es una parte de la estructura de memoria de la Máquina Virtual de Java (JVM). Se utiliza para almacenar metadatos de clases, campos estáticos y código de métodos. La memoria para el Área de Método se asigna al inicio de la JVM y se comparte entre todos los hilos que se ejecutan en la JVM.

Las características clave del Área de Método incluyen:

Metadatos de Clase: El Área de Método almacena metadatos sobre las clases, como el nombre de la clase, métodos, campos y modificadores de acceso. Esta información es utilizada por la JVM durante la ejecución del programa.

Campos Estáticos: Las variables estáticas y sus valores se almacenan en el Área de Método. Estos valores se comparten entre todas las instancias de una clase.

Código de Método: El bytecode real de los métodos (código Java compilado) se almacena en el Área de Método. Cuando se llama a un método, la JVM recupera el bytecode de esta área y lo ejecuta.

Piscina Constante: El Área de Método también contiene la piscina constante, que es una tabla de referencias simbólicas y constantes utilizadas en la clase. Incluye literales de cadena, constantes numéricas y referencias a métodos y campos.

Pilas de Métodos Nativos: También llamadas pilas C, las pilas de métodos nativos no están escritas en lenguaje Java. Esta memoria se asigna para cada hilo cuando se crea y puede ser de naturaleza fija o dinámica.

Registros del Contador de Programa (PC): Cada hilo de la JVM que lleva a cabo la tarea de un método específico tiene asociado un registro del contador de programa. El método no nativo tiene un PC que almacena la dirección de la instrucción de JVM disponible, mientras que en un método nativo, el valor del contador de programa es indefinido. El registro del contador de programa es capaz de almacenar la dirección de retorno o un puntero nativo en algunas plataformas específicas.

En Java, el Contador de Programa (PC) es un registro que forma parte de la Máquina Virtual de Java (JVM). El PC realiza un seguimiento de la dirección de la instrucción que se está ejecutando actualmente en el bytecode de un programa Java. A veces también se le llama “puntero de instrucciones”.

El Contador de Programa es un componente crucial en la ejecución de programas Java. Cuando se compila un programa Java, el código fuente se traduce a bytecode, que es un conjunto de instrucciones que la JVM puede entender. El Contador de Programa ayuda a la JVM a realizar un seguimiento de cuál instrucción de bytecode se está ejecutando actualmente.

A medida que avanza el programa, el Contador de Programa se actualiza para señalar la siguiente instrucción a ejecutar. Juega un papel clave en el flujo de control dentro del programa, determinando la secuencia de instrucciones a ejecutar.

Aquí hay una explicación simplificada de cómo funciona el Contador de Programa:

Inicialización: El Contador de Programa se inicializa con la dirección de la primera instrucción de bytecode que se va a ejecutar.

Ejecución: A medida que se ejecuta cada instrucción de bytecode, el Contador de Programa se actualiza para señalar la siguiente instrucción en secuencia.

Ramificación: En el caso de ramificaciones condicionales o incondicionales (como declaraciones if o bucles), el Contador de Programa se modifica para saltar a la dirección apropiada en el bytecode.

Llamadas a Métodos: Cuando se llama a un método, el Contador de Programa se actualiza para señalar la primera instrucción del método llamado. Cuando el método se completa, el Contador de Programa se restaura a su valor anterior.

El Contador de Programa es una parte integral del modelo de ejecución de la JVM, asegurando que se siga la secuencia correcta de instrucciones durante la ejecución de un programa Java. Ayuda a gestionar el flujo de control y admite funciones como la invocación de métodos, ramificación y bucles.