¿Es Java un lenguaje de programación compilado o interpretado?

169

En el pasado he usado C ++ como lenguaje de programación. Sé que el código escrito en C ++ pasa por un proceso de compilación hasta que se convierte en el código objeto "código máquina".

Me gustaría saber cómo funciona Java a ese respecto. ¿Cómo escribe el usuario el código Java que ejecuta la computadora?

nombre para mostrar
fuente
14
C ++ podría ser interpretado. Hay algunos intérpretes de C por ahí.
Tom Hawtin - tackline

Respuestas:

220

Las implementaciones de Java suelen utilizar un proceso de compilación de dos pasos. El compilador de Java compila el código fuente de Java a bytecode . El bytecode es ejecutado por una máquina virtual Java (JVM). Las JVM modernas utilizan una técnica llamada compilación Just-in-Time (JIT) para compilar el código de bytes a las instrucciones nativas entendidas por la CPU de hardware sobre la marcha en tiempo de ejecución.

Algunas implementaciones de JVM pueden elegir interpretar el código de bytes en lugar de JIT compilándolo en código máquina y ejecutándolo directamente. Si bien esto todavía se considera un "intérprete", es bastante diferente de los intérpretes que leen y ejecutan el código fuente de alto nivel (es decir, en este caso, el código fuente de Java no se interpreta directamente, el bytecode, salida del compilador de Java, sí).

Es técnicamente posible compilar Java a código nativo antes de tiempo y ejecutar el binario resultante. También es posible interpretar el código Java directamente.

Para resumir, dependiendo del entorno de ejecución, el código de bytes puede ser:

  • compilado antes de tiempo y ejecutado como código nativo (similar a la mayoría de los compiladores de C ++)
  • compilado justo a tiempo y ejecutado
  • interpretado
  • ejecutado directamente por un procesador compatible (bytecode es el conjunto de instrucciones nativo de algunas CPU)
Mehrdad Afshari
fuente
20
En realidad, algunas JVM de HotSpot comienzan interpretando códigos de bytes, y solo las compilan en código nativo después de que han descubierto lo que vale la pena compilar y han reunido algunas estadísticas sobre cómo se está ejecutando el código; por ejemplo, para descubrir la ruta más común tomada en cada rama condicional.
Stephen C
1
De ahí el término 'Hotspot' :) Lo hace a lo que se ejecuta a menudo, para obtener una optimización.
Mediodía Seda
44
Puede apagar el intérprete en HotSpot con -Xcomp. Vale la pena probar una aplicación para ver qué mala idea es.
Tom Hawtin - tackline
1
Hay una declaración: "La versión actual de Sun HotSpot JVM utiliza una técnica llamada compilación Just-in-time (JIT) para compilar el código de bytes con las instrucciones nativas que la CPU entiende en el momento de la ejecución". Tenía la impresión de que JVM es un intérprete, pero sugiere que compila aún más el código de bytes. Estoy confundido. También está escrito que lo hace sobre la marcha en tiempo de ejecución. ¿Alguien puede explicar esto también?
Anand
Ya que Java es un lenguaje interpretado, ¿cómo afectará el rendimiento o la ejecución de cualquier aplicación Java?
NAND
93

ingrese la descripción de la imagen aquí

El código escrito en Java es:

  • Primero compilado a bytecode por un programa llamado javac como se muestra en la sección izquierda de la imagen de arriba;
  • Luego, como se muestra en la sección derecha de la imagen de arriba, otro programa llamado java inicia el entorno de tiempo de ejecución de Java y puede compilar y / o interpretar el código de bytes utilizando el Intérprete de Java / Compilador JIT.

¿Cuándo interpreta Java el bytecode y cuándo lo compila? El código de la aplicación se interpreta inicialmente, pero la JVM monitorea qué secuencias de bytecode se ejecutan con frecuencia y las traduce a código de máquina para ejecución directa en el hardware. Para el código de bytes que se ejecuta solo unas pocas veces, esto ahorra el tiempo de compilación y reduce la latencia inicial; Para el código de bytes ejecutado con frecuencia, la compilación JIT se utiliza para ejecutarse a alta velocidad, después de una fase inicial de interpretación lenta. Además, dado que un programa pasa la mayor parte del tiempo ejecutando una minoría de su código, el tiempo de compilación reducido es significativo. Finalmente, durante la interpretación inicial del código, se pueden recopilar estadísticas de ejecución antes de la compilación, lo que ayuda a realizar una mejor optimización.

nombre para mostrar
fuente
¿Es debido al código de bytes en caché que Java usa mucha memoria?
Pedro Gordo
3
@sedulam: Una 'gran cantidad de memoria' es una declaración confusa. La gestión de la memoria de Java es bastante sencilla: las tres generaciones es lo que utiliza la JVM para la creación y el mantenimiento de sus objetos. Esta otra respuesta SO puede ser útil para usted.
displayName
Con la explicación anterior, teóricamente, el código compilado de C ++ siempre será más rápido que el código Java lógicamente similar, ya que siempre habrá una parte del archivo .class que JIT decide no transformar en código máquina. En otras palabras, java nunca puede alcanzar la velocidad de ejecución de metal desnudo que C ++ ha demostrado. ¿Es esta suposición correcta?
DevdattaK
@DevdattaK: No conozco tanto C ++, pero supongo que para programas más pequeños y especializados, Java puede darle el resultado más rápido porque no perdería tiempo compilando esas porciones de código donde no hay mucha velocidad disponible.
displayName
1
@DevdattaK su suposición se discute en esta página wiki en.m.wikipedia.org/wiki/Java_performance?wprov=sfla1 En resumen, no siempre es cierto.
Sundar Rajan el
57

Los términos "lenguaje interpretado" o "lenguaje compilado" no tienen sentido, porque cualquier lenguaje de programación puede ser interpretado y / o compilado.

En cuanto a las implementaciones existentes de Java, la mayoría implica un paso de compilación para bytecode , por lo que implican compilación. El tiempo de ejecución también puede cargar bytecode dinámicamente, por lo que siempre se necesita algún tipo de intérprete de bytecode. Ese intérprete puede o no utilizar a su vez la compilación de código nativo internamente.

En la actualidad, la compilación parcial justo a tiempo se utiliza para muchos idiomas que alguna vez se consideraron "interpretados", por ejemplo, JavaScript.

starblue
fuente
55
Además, el motor de ejecución de JavaScript V8 de Google no solo realiza una compilación parcial justo a tiempo. Es siempre compila a código nativo, de hecho, ni siquiera V8 tiene un intérprete. Tiene solamente el compilador (similar a Maxine, pero a diferencia de Maxine V8 tiene sólo un compilador). Los tres ejemplos (GCJ, Maxine y V8) demuestran su punto aún más fuertemente: no existe un lenguaje interpretado o un lenguaje compilado. Un idioma no se interpreta ni se compila. Un idioma simplemente es (en realidad es una cita de Shriram Krishnamurthi).
Jörg W Mittag el
3
¿Por qué estás hablando de JavaScript en una pregunta de Java?
Koray Tugay
1
@KorayTugay Solo como un ejemplo. Ciertamente no quiero implicar que Java y Javascript tengan algo en común aparte de las primeras cuatro letras de su nombre.
Starblue
¿Al menos una diferencia en el lenguaje interpretado y compilado no significa que un lenguaje binario compilado no puede cambiar su flujo de ejecución en ningún momento, mientras que un lenguaje interpretado es muy obediente a algunas de las funciones actuales de las funciones? Las bibliotecas en C son una opción, mientras que en otros lenguajes no puede tener un objeto de matriz sin una extensión binaria en C que pueda actualizarse o ser un código completamente diferente en otra plataforma. El lenguaje de secuencias de comandos podrá ejecutarse en ambos, mientras que el lenguaje compilado necesitaría un binario diferente para ejecutarse
Eaton Emmerich
53

Java se compila en bytecode, que luego entra en la máquina virtual Java, que lo interpreta.

Seda del mediodía
fuente
33
... pero no estrictamente exacto.
Stephen C
2
JVM podría elegir no "interpretar" el código de bytes. Puede JIT compilarlo y ejecutarlo directamente.
Mehrdad Afshari
1
JIT técnicamente no lo está ejecutando directamente. Solo recuerda cómo se ejecutó.
cletus
Mehrdad: De acuerdo, no describí las posibles operaciones JIT aquí, ya que considero que depende de la JVM, y de todos modos mantenía mi respuesta simple :)
Noon Silk
77
cletus: Después de JIT, se ejecutará directamente. JIT está leyendo un código de bytes (por ejemplo, un método completo ) y compilando el código de máquina y saltando a él.
Mehrdad Afshari
12

Java es un lenguaje de programación compilado, pero en lugar de compilar directamente en código máquina ejecutable, se compila en una forma binaria intermedia llamada código de bytes JVM. El código de bytes se compila y / o interpreta para ejecutar el programa.

Sam Harwell
fuente
11

Tipo de ambos. En primer lugar, Java compiló (algunos preferirían decir "traducido") a bytecode, que luego compiló o interpretó según el estado de ánimo de JIT.

maykeye
fuente
32
Esa es una avanzada pieza de software, tener estados de ánimo desarrollados :)
Thorarin
55
El JIT es de hecho un software muy sofisticado, que puede hacer optimizaciones basadas en información de tiempo de ejecución (como un generador de perfiles), que un compilador anticipado no puede hacer (porque no tiene información sobre el comportamiento de tiempo de ejecución de un programa antes de tiempo). Pero probablemente no tenga realmente ánimo ... :-)
Jesper
5

Java hace tanto compilación como interpretación,

En Java, los programas no se compilan en archivos ejecutables ; se compilan en bytecode (como se discutió anteriormente), que la JVM (Java Virtual Machine) interpreta / ejecuta en tiempo de ejecución. El código fuente de Java se compila en bytecode cuando usamos el compilador javac. El bytecode se guarda en el disco con la extensión de archivo .class .

Cuando se va a ejecutar el programa, el bytecode se convierte y el bytecode se puede convertir, utilizando el compilador Just-In-Time (JIT). El resultado es un código de máquina que luego se alimenta a la memoria y se ejecuta.

Javac es el compilador de Java que compila el código de Java en Bytecode. JVM es una máquina virtual Java que ejecuta / interpreta / traduce Bytecode en código de máquina nativo. En Java, aunque se considera un lenguaje interpretado, puede usar la compilación JIT (Just-in-Time) cuando el código de bytes está en la JVM. El compilador JIT lee los códigos de bytes en muchas secciones (o en su totalidad, rara vez) y los compila dinámicamente en código de máquina para que el programa pueda ejecutarse más rápido, y luego se almacena en caché y se reutiliza más tarde sin necesidad de volver a compilar. Entonces, la compilación JIT combina la velocidad del código compilado con la flexibilidad de interpretación.

Un lenguaje interpretado es un tipo de lenguaje de programación para el cual la mayoría de sus implementaciones ejecutan instrucciones directa y libremente, sin compilar previamente un programa en instrucciones de lenguaje máquina. El intérprete ejecuta el programa directamente, traduciendo cada declaración en una secuencia de una o más subrutinas ya compiladas en código máquina.

Un lenguaje compilado es un lenguaje de programación cuyas implementaciones suelen ser compiladores (traductores que generan código de máquina a partir del código fuente) y no intérpretes (ejecutores paso a paso del código fuente, donde no se lleva a cabo una traducción previa al tiempo de ejecución)

En implementaciones modernas de lenguaje de programación como en Java, cada vez es más popular que una plataforma brinde ambas opciones.

principal
fuente
Debería ser "el bytecode puede convertirse" en lugar de " se convierte". Las especificaciones Java definen bytecode. Ya sea que ese bytecode se ejecute (a) directamente en hardware , (b) a través de un intérprete, (c) compilado de antemano, o (d) compilado parcialmente sobre la marcha en tiempo de ejecución , todos quedan como detalles de implementación. Tenga en cuenta que las cuatro opciones han sido utilizadas por varias implementaciones de Java del mundo real.
Basil Bourque
Gracias por señalar esto. Entonces, ¿qué sucede si el código de bytes no se convierte en código de máquina? Puedo pensar en un escenario donde el bytecode es el conjunto de instrucciones nativo para algunos procesadores y luego no hay necesidad de una conversión. O me estoy perdiendo algo.
primer
Haga clic en el enlace que le di para la tecnología Jazelle DBX (Direct Bytecode eXecution) , donde un subconjunto de JVM bytecode son las instrucciones de máquina nativas de la CPU (algo así como). Sin eso, obtiene el código de máquina generado a partir del código de bytes (a) del intérprete (sobre la marcha), (b) desde el compilador antes de tiempo, o (c) sobre la marcha con un compilador justo a tiempo ( interpretado al principio, y luego a veces compilado y almacenado en caché durante la ejecución).
Basil Bourque
-2

Java es un lenguaje compilado de bytes dirigido a una plataforma llamada Java Virtual Machine que está basada en la pila y tiene algunas implementaciones muy rápidas en muchas plataformas.

hobbs
fuente
1
¿Qué significa "compilación de bytes"?
Jesper
2
@Jesper: "Compilado por byte" generalmente significa "compilado a bytecode". "Bytecode" es un término general que cubre cualquier tipo de código intermedio no textual (generalmente no ejecutable por máquina).
Greg Hewgill
-3

Cita de: https://blogs.oracle.com/ask-arun/entry/run_your_java_applications_faster

Los desarrolladores de aplicaciones pueden desarrollar el código de la aplicación en cualquiera de los diversos sistemas operativos que están disponibles actualmente en el mercado. El lenguaje Java es agnóstico en esta etapa para el sistema operativo. El brillante código fuente escrito por el desarrollador de aplicaciones Java ahora se compila en código de bytes de Java, que en la terminología de Java se conoce como compilación del lado del cliente. Esta compilación del código de bytes de Java es lo que permite a los desarrolladores de Java "escribir una vez". El código de Java Byte puede ejecutarse en cualquier sistema operativo y servidor compatibles, por lo tanto, el código fuente es independiente del sistema operativo / servidor. Después de la creación del código de Java Byte, la interacción entre la aplicación Java y el SO / Servidor subyacente es más íntima. El viaje continúa: el marco de aplicaciones empresariales ejecuta estos códigos de bytes de Java en un entorno de tiempo de ejecución que se conoce como Java Virtual Machine (JVM) o Java Runtime Environment (JRE). La JVM tiene vínculos estrechos con el sistema operativo y el hardware subyacentes porque aprovecha los recursos ofrecidos por el sistema operativo y el servidor. El código de bytes de Java ahora se compila en un código ejecutable en lenguaje de máquina que es específico de la plataforma. Esto se conoce como compilación del lado del servidor.

Entonces diría que Java es definitivamente un lenguaje compilado.

Teo
fuente