Máquina virtual Java: áreas de datos en tiempo de ejecución

La especificación JVM define ciertas áreas de datos en tiempo de ejecución que se necesitan durante la ejecución del programa. Algunos de ellos se crean mientras se inicia la JVM. Otros son locales de los hilos y se crean solo cuando se crea un hilo (y se destruyen cuando se destruye el hilo). Estos se enumeran a continuación:

Registro de PC (Contador de programas)

Es local para cada hilo y contiene la dirección de la instrucción JVM que el hilo está ejecutando actualmente.

Apilar

Es local para cada hilo y almacena parámetros, variables locales y direcciones de retorno durante las llamadas a métodos. Se puede producir un error de StackOverflow si un subproceso exige más espacio de pila del permitido. Si la pila se puede expandir dinámicamente, aún puede generar OutOfMemoryError.

Montón

Se comparte entre todos los hilos y contiene objetos, metadatos de clases, matrices, etc., que se crean durante el tiempo de ejecución. Se crea cuando se inicia la JVM y se destruye cuando se cierra la JVM. Puede controlar la cantidad de montón que su JVM demanda del sistema operativo usando ciertos indicadores (más sobre esto más adelante). Se debe tener cuidado de no exigir demasiado o menos memoria, ya que tiene importantes implicaciones en el rendimiento. Además, el GC gestiona este espacio y elimina continuamente los objetos muertos para liberar el espacio.

Área de método

Esta área de tiempo de ejecución es común a todos los subprocesos y se crea cuando se inicia la JVM. Almacena estructuras por clase como el grupo constante (más sobre esto más adelante), el código para constructores y métodos, datos de métodos, etc. El JLS no especifica si esta área necesita ser recolectada de basura y, por lo tanto, implementaciones JVM puede optar por ignorar GC. Además, esto puede expandirse o no según las necesidades de la aplicación. La JLS no exige nada con respecto a esto.

Pool constante de tiempo de ejecución

La JVM mantiene una estructura de datos por clase / por tipo que actúa como la tabla de símbolos (una de sus muchas funciones) mientras vincula las clases cargadas.

Pilas de métodos nativos

Cuando un hilo invoca un método nativo, ingresa a un nuevo mundo en el que las estructuras y restricciones de seguridad de la máquina virtual Java ya no obstaculizan su libertad. Es probable que un método nativo pueda acceder a las áreas de datos en tiempo de ejecución de la máquina virtual (depende de la interfaz del método nativo), pero también puede hacer cualquier otra cosa que desee.

Recolección de basura

La JVM gestiona todo el ciclo de vida de los objetos en Java. Una vez que se crea un objeto, el desarrollador ya no tiene que preocuparse por él. En caso de que el objeto se muera (es decir, ya no se hace referencia a él), el GC lo expulsa del montón utilizando uno de los muchos algoritmos: GC serie, CMS, G1, etc.

Durante el proceso de GC, los objetos se mueven en la memoria. Por lo tanto, esos objetos no se pueden utilizar durante el proceso. Toda la aplicación debe detenerse mientras dure el proceso. Estas pausas se denominan pausas de "detener el mundo" y son una enorme sobrecarga. Los algoritmos de GC apuntan principalmente a reducir este tiempo. Discutiremos esto con gran detalle en los siguientes capítulos.

Gracias al GC, las pérdidas de memoria son muy raras en Java, pero pueden ocurrir. Veremos en los capítulos posteriores cómo crear una fuga de memoria en Java.