La paradoja de la máquina virtual y el interprete

Nota: durante todo el artículo se habla de máquina virtual de proceso, es decir, por ejemplo, la de Java, no de sistema, por ejemplo, VirtualBox.

Hace tiempo, estaba hablando con un amigo, y hablando hablando, se de pronto nos surgió una paradoja, que nos dejó de piedra…

Todo empezó cuando uno de los dos (no recuerdo cual) dijo que no era lo mismo una máquina virtual, que un interprete, y el otro, le contestó: claro que no, joder, eso es de informática básica, por dios.

Pero se hizo el silencio, ambos estábamos buscando rápidamente en nuestra cabeza una diferencia clave, una diferencia demoledora entre máquina virtual e interprete, pero no dábamos con ella, dimos con algunas, evidentemente, pero todas, nos dimos cuenta enseguida, o bien eran diferencias entre implementaciones concretas, por ejemplo, entre la VM de Java y el interprete de PHP, o bien eran diferencias filosóficas, en plan: la VM está pensada para ser…

Tras un rato de silencio, uno de los dijo:

¿Y cual es la diferencia técnica de base, entre una máquina virtual, y un interprete?

La pregunta sonaba de los mas absurdo, ambos sabíamos perfectamente lo que es un compilador, un pre-compilador, etc, vaya, no era un problema de falta de conocimientos en ese ámbito, pero notábamos que algo fallaba…que no dábamos con esa diferencia de base, que diferencia cosas que todo informático, sabe que son como la noche y el día.

Tras pensarlo un rato, yo dije: está claro! La máquina virtual ejecuta código medio, mientras que el interprete procesa código de alto nivel. Es decir, uno procesa código de bajo nivel, y otro de alto nivel. Pero mi amigo enseguida desmontó mi teoría hablando de Javascript.

Los interpretes de javascript, por como funcionan, son llamados máquinas virtual, por ejemplo:

http://code.google.com/p/v8/

Se puede leer claramente como google se refiere a su V8 como VM (virtual machine).

Bueno, entonces si ambos pueden procesar el mismo tipo de código, que diferencia hay?

Tras pensar un rato, mi colega dijo: la VM está pensada para abstraer al programa del hardware, y yo contesté: y PHP no? y perl no? Es exactamente lo mismo.

Durante mucho rato, fueron surgiendo ideas e ideas, pero todas, eran diferencias filosóficas, diferencias entre cierto interprete, y cierta VM…pero nunca algo genérico, aplicable a cualquier VM.

Al llegar a casa, fui a wikipedia, a sentir como si volviese a estudiar informática de nuevo, y abrí la siguiente página en el navegador:

http://en.wikipedia.org/wiki/Virtual_machine#Process_virtual_machines

Y leo la siguiente frase, muy interesante: Process VMs are implemented using an interpreter;

Según la wikipedia, lo que sucede es que una VM utiliza internamente un interprete, es decir, una VM es un interprete, y algo mas, veamos que mas:

A process VM, sometimes called an application virtual machine, runs as a normal application inside an OS and supports a single process

Eso, se puede aplicar al interprete de Python, de perl, etc.

It is created when that process is started and destroyed when it exits.

Vale, igual que el interprete de python o php.

Its purpose is to provide a platform-independent programming environment that abstracts away details of the underlying hardware or operating system, and allows a program to execute in the same way on any platform.

Vale, como TCL, por ejemplo, que es un interprete. O cualquier otro interprete, vaya.

performance comparable to compiled programming languages is achieved by the use of just-in-time compilation.

Vale, tal como hace python, no? los famosos .pyc

Después de todo esto, al final llegamos a la siguiente conclusión: no existe una diferencia técnica entre máquina virtual de proceso e interprete, es una diferencia de concepto, es decir, quien hace una VM, tiene una forma de pensar, y quien hace un interprete, otra, y eso, se refleja en el resultado final, pero como conceptos base, no encontramos diferencia.

Aprovechando una charla con un developer de mono, mi colega le preguntó sobre esta paradoja, que parece algo evidente, pero que no conseguimos resolver, y no nos dejaba vivir, el developer, tras pensarlo un buen rato, nos dijo que la diferencia era en como finaliza un interprete, y como finaliza una máquina virtual, al finalizar, la máquina virtual puede no finalizar (a diferencia de lo que nos había dicho wikipedia) y el interprete debe finalizar.

Pero esto no nos convencía, es algo mas de implementación que de concepto, y podría existir un interprete que no finalizase, sino esperase mas scripts para ejecutar.

Al final, comido por las dudas, viví agobiado un tiempo, hasta que un día, di con la respuesta, y era bastante tonta, ciertamente.

Una vez con la respuesta, se me ocurrió una idea, llevar la pregunta al meneame (craso error):

http://meneame.net/notame/jcarlosn/119061

Y un par de usuarios, tal como me esperaba, ante lo evidente que parece la pregunta en primera instancia, me tacharon de ignorante, de no saber lo que era un compilador, etc etc…pero a la hora de dar una respuesta, me dieron la siguiente: Una máquina virtual ejecuta código intermedio, no entendible por el ser humano, mientras que un interprete ejecuta código de alto nivel, entendible por el ser humano.

Esta respuesta se cae por su propio peso, en primer lugar, eso depende de la implementación de VM, por ejemplo, la V8 de google, incluida en chrome, ejecuta código javascript, de alto nivel, en segundo lugar, para procesar el MSIL, por poner un ejemplo, la plataforma .net, utiliza un interprete, eso es evidente.

Al final, después de mucho dolor de cabeza e intrigas, tengo una bonita paradoja que me sirve para diferenciar a informáticos que van de superdioses, de la gente que realmente sabe.

Siempre que he hecho está pregunta a un desarrollador de algún proyecto de software libre, se lo ha pensado, a contestado, y alguno, ha dado en el clavo, mientras que siempre (al menos de momento) que se la he hecho a un estudiante o joven informático español, se ha réido de mi, me ha descalificado, se ha reído de la pregunta, pero finalmente, no la ha contestado.

De hecho, otro dato curioso de la paradoja, es que de momento el 100% de los preguntados estudiantes de informática españoles, responden asumiendo que hablamos de la VM de Java, enhorabuena a los de marketing de SUN.🙂

Por cierto, una nota para que nadie se ofenda, no quiero decir que ningún estudiante de informática español pueda contestar esto, sino que yo he tenido una mala experiencia🙂

26 Responses to “La paradoja de la máquina virtual y el interprete”


  1. 1 vierito5 febrero 25, 2009 a las 10:23 pm

    Muy buen artículo, sin duda me quedo con la versión de que en el fondo es lo mismo enfocado de formas distintas. Es una línea demasiado delgada como para no cruzarla mediante una afirmación categórica. Nunca me lo había planteado.

  2. 2 Adrián febrero 25, 2009 a las 10:44 pm

    Muy buen post…
    En cuanto al tema, es cierto… a medida que leía estaba pensando lo que decías, y es cierto que es más ‘lo que quiera hacer’ y no suelen partir de una base común. A todo esto, muy personalmente (y equivocadamente) te habría contestado que la máquina virtual corre su código sobre una ‘base’ común (Java, V8 para JavaScript) y el intérprete simplemente ejecuta código como si de un binario se tratase (pero pasando por el compilador “al-vuelo”).

    Eso sí, como tampoco tengo gran idea de programación no puedo hablar demasiado… seguro que ya la he líado. Y la cuestion, muy buena… el post también🙂

  3. 3 manuel febrero 25, 2009 a las 11:20 pm

    uno ejecuta código precompilado (o preprocesado) y el otro lo hace directamente ?

  4. 4 jcarlosn febrero 25, 2009 a las 11:24 pm

    manuel, muchos interpretes modernos precompilan el código antes de ejecutarlo, de hecho, es una característica de python, entre otros, y cada vez mas extendida entre los interpretes.

  5. 5 Nodens febrero 25, 2009 a las 11:26 pm

    A ver, así a ojo de buen cubero, corrijanme si me equivoco.

    La máquina virtual crea un espacio de direcciones interno con en el que puede albergar varios procesos sobre el y abstrae totalmente a los procesos de la máquina que hay por debajo resolviendo ella misma por ejemplo problemas de acceso a recursos.

    El interprete es un solo proceso, si queremos lanzar X programas interpretados se lanzan X procesos interprete y en este caso los programas luchan individualmente por los recursos de la máquina.

  6. 6 jcarlosn febrero 25, 2009 a las 11:33 pm

    Muy bueno tu comentario Nodens, creo que es una de las mejores diferencias que he oído, desde que le doy vueltas a esta pregunta, sobretodo el hecho de que:

    El interprete es un solo proceso, si queremos lanzar X programas interpretados se lanzan X procesos interprete y en este caso los programas luchan individualmente por los recursos de la máquina.

    Muy buena diferenciación, gracias🙂

    Aun y así, en java por ejemplo, cada ejecución de java es una instancia de la VM, por separado, y no alberga varios procesos, de hecho, así lo explica wikipedia en la sección de maquinas virtuales de procesos, por lo cual, esto es una diferencia real, pero que por algún motivo u otro, en la actualidad no se cumple para todas las VM.

    Un saludo!

  7. 7 Adrián febrero 25, 2009 a las 11:38 pm

    Realmente no creo que cumplan al fin y al cabo un patrón específico. O todos a interpretados (preocompilados o no) o a máquinas virtuales… por que por ejemplo entre Java y VisualBasic hay una diferencia (uno da el código que ejecuta la VM y otro da un EXE) sin embargo entre Java y PHP se van acercando. Teniendo en cuenta las características de ambos lenguajes de programación, ambos serían una aproximación a una VM siendo Java oficialmente uno, y PHP un lenguaje interpretado.

    Pero vamos, que de la misma forma aciertas: es lo que quieran los ‘inventores’, al fin y al cabo

  8. 8 Nodens febrero 25, 2009 a las 11:39 pm

    Es posible que no haya una respuesta clara ya que son conceptos ideados hace mucho que han quedado diluidos en la práctica debido a exóticas implementaciones o por ejemplo a la tendencia de los interpretes a abarcar cada vez más abstracción para facilitar cosas al programador.

  9. 9 Andrés Panitsch febrero 25, 2009 a las 11:42 pm

    Muy buen interrogante, la verdad. Personalmente me convence el comentario de Nodens respecto de los procesos. Aunque es una diferencia pequeña en realidad teniendo en cuenta lo “separados” que estaban esos conceptos en mi cabeza (hasta ahora).

    Intuitivamente, tiendo a pensar que una máquina virtual implica un conjunto de operaciones definido por ella “la VM XX no permite el acceso al disco del usuario”, mientras que un intérprete debe implementar todas las operaciones definidas por el lenguaje.

    … pero no estoy muy convencido de ello, es solo una idea intuitiva.

  10. 10 vmlinuz febrero 26, 2009 a las 5:09 am

    segun mi sentido comun, la diferencia radica mas bien en el ambito de la memoria. los procesos en una vm estan englobados o gobernados por la instancia de la vm. mientras q el interprete se implementa sobre la misma plataforma en la que corre el mismo en un nivel mas basico. solo digo ^^ es probable q este equivocado.

  11. 11 capitan.cambio febrero 26, 2009 a las 10:11 am

    Hola,

    Primero felicitarte por le post, me ha tenido un buen ratillo pensando cual es la diferencia entre ambos conceptos. En principio creo que es mayoritariamente una cuestión de diseño, la máquina virtual ejecuta código intermedio o encapsula al proceso de ejecutcion en una computadora virtual que se comporta de forma análoga a una física (la de java, la de python …). Y aqui ojo,si te lees la docuemtnación de V8 dice :”V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter”. En los ejemplos de cómo usarla primero hay que compilar el código JS y luego ejecutarlo. No hacer un eval después de instanciar el interprete, en este paso se harán optimizaciones en el código como pualquier otro compilador de una forma eficiente, algo que en los lenguajes puramente interpretados es más complicado de conseguir.

  12. 12 HenryGR febrero 26, 2009 a las 11:20 am

    ¡Felicidades!
    Una magnífica observación y buen planteamiento.
    Yo me atrevo a plantear una posible diferencia, quizá más conceptual que real:
    Un interprete espera instrucciones en un lenguaje determinado y dentro de una colección limitada.
    La VM hace lo mismo, pero además ofrece una serie de funciones pre implementadas para facilidad del usuario; por ejemplo manejo de iframes o de dispositivos externos.

  13. 13 lector febrero 26, 2009 a las 6:42 pm

    Yo veo dos diferencias bastante claras:
    – Java por ejemplo necesita primero pasar por un compilador. Se obtiene un código objeto pero que en lugar de ser ejecutado directamente por el sistema operativo lo ejecuta otro programa: la máquina virtual.

    – Los interpretes tradicionalmente van ejecutando las intrucciones “sobre la marcha”. Así, en un script en PHP, puede haber un error en la línea X que con JAva no sería posible ni compilar a objeto.

    Si os fijais las diferencias en las palabras afectan a los propios programas. A un programa en PHP se le suele llamar script (guion) mientras que nunca se habla de scripts en Java. Esto es así porque un programa en PHP es simplemente un guión escrito directamente por el programador para el interprete.

  14. 14 oskarloko febrero 26, 2009 a las 11:53 pm

    Me ha picado la curiosidad, y he visitado esa fuente de sabiduria que el la wikipedia

    http://en.wikipedia.org/wiki/Interpreter_(computing)

    Donde denominan a la JVM un interprete de tercer nivel, es decir

    Interpeter type 3.- explicitly executes stored precompiled code[1] made by a compiler which is part of the interpreter system

    Para mi – quizás sea fruto de como he aprendido informatica que de una diferencia técnica real – veo el interprete como algo más simple que la VM de proceso: estya última utiliza codigo precompilado, threads nativos (no ‘green threads’), compilador JIT, etc…

    [tb en meneame]

    Un interprete intenta ejecutar un codigo dentro de un SO; una VM intenta abarcar un SO para ejecutar un codigo

  15. 15 joselito febrero 27, 2009 a las 12:16 am

    Sin tener ni puta idea, al leer post y comentarios, me ha llegado una analogía evolutiva. Funcionalmente, el ala de un ave y un murcielago son similares, pero tienen orígenes diferentes y morfología distinta.
    Saludos

  16. 16 helmer febrero 28, 2009 a las 11:38 am

    Felicidades por el post, resulta muy estimulante desmontar cosas que se dan por sentadas usando la “duda metódica” cartesiana, que es la que nos lleva al fondo de la cuestión.

    Aunque estoy bastante pez en este tema, intuitivamente se me ocurre que al menos una VM dispone de un repertorio de instrucciones propio al igual que la arquitectura de una máquina física, mientras que el intérprete creo que no dispone de él, corrígeme si me equivoco (es posible que esté diciendo una chorrada) xD

    Saludos

  17. 17 ¿Cuál es la diferencia entre máquina virtual e intérprete? marzo 1, 2009 a las 4:37 pm

    […] Os dejo un enlace a un post del blog de de Jose Carlos Norte en el que plantea las diferencias entre una máquina virtual y un intérprete […]

  18. 18 esteve marzo 4, 2009 a las 7:57 pm

    El problema que veo es que habéis intentado comparar dos cosas que están a niveles diferentes. Un intérprete coge algo escrito en X y le aplica una función que lo evalua. Por ejemplo, pasa X a un AST, luego a código intermedio y luego lo evalua sobre la marcha, además de que el código intermedio es estático. En el caso de Python, una vez que se genera el bytecode, éste no se modifica.

    Lo contrario de un intérprete, no es una máquina virtual, sino un compilador. Éste último puede traducir a código nativo directamente o hacerlo en tiempo de ejecución.

    De hecho, en el caso de Java, las primeras versiones de la máquina virtual ejecutaban el código usando un intérprete. No fue hasta que Symantec (si no recuerdo mal), que implementó el primer JIT para Java, que se empezó a mover el tema de los compiladores en tiempo de ejecución en el mundillo de Java:

    http://www.symantec.com/region/can/eng/press/1998/n980114.html

    ¿Porqué a la de Java se le llama máquina virtual y a la de Python no? Probablemente por la misma razón que a la de V8 (o Rhino) sí se le llama así y a la de la versión original de SpiderMonkey no (el primer intérprete de Javascript). Tiene que ver más con que el código que se produce a partir del código Javascript original es más rico, el cual se puede optimizar. De hecho, un intérprete podría no generar ninguna representación intermedia y evaluar sobre la marcha.

    El bytecode de Python ayuda a la ejecución de los programas, pero no es optimizable fácilmente (porque no proporciona la suficiente información). Ya sé que existe la la opción -O del intérprete de Python que genera bytecode optimizado, pero éste no es traducido a un lenguaje intermedio ni es optimizable (ya está optimizado cuando se genera). Es el problema que tenía Psyco, al no tener suficiente información sobre el programa, era complicado que optimizara demasiado.

    Si lo comparas con IronPython (Python sobre la máquina virtual de .Net/Mono) o Jython (sobre la JVM), estos generan código intermedio para la máquina virtual, para que luego éstas puedan optimizarlo según crean conveniente.

    También puede ser porque comercialmente VM suena mejor😉

  19. 19 David marzo 14, 2009 a las 3:37 pm

    Muy interesante el post.

    Hace mucho tiempo leí este ejemplo sobre la diferencia entre compilador e interprete.

    – Un interprete es como un interprete real. Es decir alguien te cuenta algo en un idioma y el interprete lo traduce simultaneamente para a tu idioma para que lo entiendas.

    – Un compilador es como un traductor. Alguien escribe un documento, tu se lo entregas a un traductor y tiempo despues este te lo devuelve en tu idioma para que lo comprendas.

    Ahora tendré que actualizarlo:

    – Una máquina virtual es como una obra en otro idioma que entregas a un traductor. Tiempo despues el traductor te devuelve la obra en tu idioma, la lees y te das cuenta que lo que cuenta la obra es esta misma historia.😉

  20. 20 Scipion abril 29, 2009 a las 12:37 am

    Muy bueno el post. Por cierto, hay comentarios de gente que parece que no se lo hayan leido.
    Pero sí, es cierto, es muy delgada la linea que separa maquina virtual y script. De hecho he oido tanto maquina virtual de javascript como interprete de javascript, es decir que nadie lo tiene muy claro. Yo tb pienso que la diferencia es de filosofia más que tecnica, porque como cada lenguaje es de su padre y de su madre, estos le ponen el nombre que quieren.

  21. 21 drasius julio 29, 2009 a las 6:17 pm

    Cuando las premisas son erróneas la conclusión por ende también lo será(o no depende a lo mejor hasta la lógica la aplica mal).
    Lo primero desmentir algunas cosas que dice este artículo, primero V8 como ya han dicho por ahí no lo calificaría por supuesto de interprete y va un paso más alla de la máquina virtual.Es decir no lee las instrucciones en javascript directamente mientras se ejecuta el programa. Lo compila a código máquina nativo en ensamblador y luego desde una especie de cache lo ejecuta(creo que no hay cosa más rapida xd).

    Lo segundo quién dijo que python es un intérprete? Es claramente una máquina virtual, genera su código intermedio la primera vez y luego usa este para compilar en ejecución a código nativo(JIT). El just in time consta de dos fases de precompilado y compilado en ejecución.Además que en muchas implementaciones el tema de memoria e hilos funciona bien.

    El intérprete simplemente coge las instrucciones escritas en un lenguaje y las va leyendo a medida que se procesa el script (por cada ejecución tiene que volverlas a compilar a código nativo),con todos los pasos intermedios que conlleva además de no poseer una infraestructura de memoria, objetos y recolectores de basura como en los otros casos.

    • 22 .teri enero 9, 2010 a las 7:08 pm

      Pues lo que tengo estudiado de lenguajes interpretados y máquina virtuales de todo tipo he llegado a la conclusión que son la misma cosa solamente que con nombres distintos. Ambas(?), máquina virtual de Java e intérprete necesitan el código byte para ejecutar las instrucciones contenidas en ella, da igual que sea precocinado el código o no (en este caso pues genera el código byte); ambas tienen que gestionar los recursos de memoria y gestionan los accesos a hardware si se quiere o no. Lo de los procesos, que se multihilo o lo que sea se puede implementar ya como parte del intérprete/máquina virtual o bajo la forma de un módulo o biblioteca que lo implementa. Bueno, así lo tengo entendido yo.

  22. 23 iván escudero caján julio 6, 2014 a las 5:57 pm

    Por qué tanta filosofía?, una MV necesita de un compilador y el intérprete no. Es sólo eso, cuando un interprete necesite de un compilador, entonces deja de ser un intérprete. Más allá de adherirse al nombre.


  1. 1 ¿Cuál es la diferencia entre máquina virtual e intérprete? | Weterede! Trackback en abril 22, 2009 a las 8:09 pm
  2. 2 La paradoja de la máquina virtual y el interprete Trackback en diciembre 27, 2010 a las 4:21 pm
  3. 3 Joselyn Trackback en noviembre 2, 2015 a las 10:42 am

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s





A %d blogueros les gusta esto: