Programando en Java: De la escritura a la ejecución

This post is also available in: English

En este artículo, voy a explicar las diferentes fases por las que pasa una aplicación en java, desde que esta en la cabeza del programador, hasta su ejecución en un sistema. Para ello me voy a basar en lo que propone Deitel en su libro “How to program in Java”.

Las fases de un programa en java son las siguientes (fases más, fases menos):

  1. Fase de Creación o Edición
  2. Fase de Compilación
  3. Fase de Carga del programa en memoria
  4. Fase de Verificación de Bytecodes
  5. Fase de Ejecución

Otros textos proponen solo 3 fases, las cuales abarcan a las descritas arribas. Ellas suelen ser:

  1. Edición
  2. Compilación
  3. Interpretación o Ejecución

Personalmente voy a elegir la primer lista para explicar, ya que me parece que es la más detallada

Fase de edición

Lo primero que hace un programador una vez que ya tiene en mente la aplicación que desea desarrollar es empezar a escribir el código. Esto es lo que se conoce como fase de edición y el resultado de la misma es el código fuente. Este es un tipo de código entendible por personas ya que suele ser parecido al íngles, pero aún esta lejos de lo que es comprensible directamente por la máquina.

Podemos escribir un programa en java usando algo tan simple como el editor de texto en windows; vi, vim o gedit en linux; o bien podemos usar una herramienta más orientada al desarrollo, o sea una IDE (Integrated Development Environment), como puede ser Eclipse, IntelliJ, Sublime, entre otras.

El archivo que contiene el código fuente de un programa en java tendrá la extensión .java. O sea, cuando en nuestro proyecto veamos archivos .java ya sabremos que estamos en frente del codigo fuente.

Un ejemplo simple de una aplicación que imprima algo en consola es la siguiente:

public class SimpleApp{

public void main(String[] args){
System.out.println("This is a simple application");
}
}

El nombre del archivo .java debe coincidir con el nombre de las clase (class), en este caso SimpleApp.java

Fase de compilación

Una vez el programador baja su idea a un código fuente, es hora de compilar el mismo.

Este proceso convierte nuestro código fuente en códigos de bytes que más tarde serán interpretados por la JVM.

A diferencia de muchos otros lenguajes, los códigos de bytes compilados, pueden ejecutarse en cualquier sistema (Linux, Windows, MacOS, etc) que tenga la JVM correspondiente. Esto les da la característica de portabilidad a los mismos, lo cual es uno de los puntos fuertes de java.

Para compilar el código fuente, puede hacerse a través de la IDE (Eclipse, IntelliJ, etc) o por consola, con el comando javac (java compiler). Para el ejemplo sería:

javac SimpleApp.java

Si todo va bien, la salida de esto es un archivo SimpleApp.class, el cual contiene los byte codes de la aplicación.

Para ejecutar este programa basta con usar el comando java SimpleApp.java, aunque también puede usarse directamente la IDE.

En mi opinión es recomendable conocer aunque sea los comandos básicos por sobre el uso de la IDE, no sea cosa de que un día lo necesitemos y no sepamos que hacer jeje.

 

Fase de Carga del programa en memoria

Cuando se ejecuta el programa en java con el comando java, entra en juego un componente llamado cargador de clases. Este, carga las clases dinámicamente en la JVM, es decir a medida que se van necesitando. Cabe recordar que la JVM es como una especie de computadora virtual, es decir que tiene su propia memoria, aunque esto signifique que a fin de cuentas se cargue en la memoria física. Lo primero que hará el cargador de clases es intentar cargar nuestro .class en memoria e ir cargando todos los .class a los que la aplicación (en el ejemplo SimpleApp.class) haga referencia. Las clases a las que la aplicación haga referencia pueden encontrarse localmente en el disco duro o bien remotamente.

Todas las JVMs incluyen un cargador de clases, el cual es conocido como cargador de clases primordial.

 

Fase de Verificación de Bytecodes

A fin de asegurar que no se violan restricciones de seguridad, a medida que se van cargando las clases en memoria, el verificador de bytecodes examina los bytecodes para asegurar que sean válidos. Por qué se hace esto? Básicamente el sistema Java run-time no confía en el código que se está cargando.

Se realizan pruebas tales como que el formato del fragmento de código sea el correcto, así como también:

  • Que no se forjen punteros
  • Que no haya violaciones de acceso a la memoria
  • Que los objetos sean accedidos por lo que son (Por ejemplo, que un objeto System siempre sea usado como System y nada más)

 

Fase de Ejecución

Esta es la fase donde la JVM ejecuta las acciones especificadas por los bytecodes cargados en su memoria.

Como mencione anteriormente, la JVM es como una especie de computadora virtual que reside en la máquina fisica. Entre otras cosas esta cuenta con una memoria virtual, que es donde se cargan los programas en java.

Los archivos .class se cargan en la memoria virtual y es la máquina virtual la que se encarga de traducir estas instrucciones que ella puede entender a instrucciones que entiende el Sistema Operativo y hardware subyacente.

Gráficamente quedaría:

JVM to OS

Como se observa, la JVM actua como una capa intermedia entre su lenguaje “máquina” (entendible por la JVM) y el sistema subyacente. Esto hace que el código compilado sea independiente de la plataforma en la cual se va a ejecutar.

A fin de ganar eficiencia en el proceso de interpretar el código que la JVM puede entender a código que sea entendible por la computadora, las JVMs actuales utilizan una técnica conocida como compilación Just in Time o JIT (También se lo conoce como HotSpot compiler). Cuando se detecta que hay byte codes que se ejecutan con frecuencia el compilador JIT los traduce a lenguaje de máquina, con lo cual la próxima vez que la JVM encuentre estos bytecodes los ejecutará directamente sin necesidad de pasar por el proceso de interpretación, sumando eficiencia a la ejecución del programa en java.

Deja un comentario

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

9 − 6 =