2010-02-05 18 views
7

Q1) ¿Por qué C# compilado inicialmente a IL y luego en tiempo de ejecución JIT cumplido y se ejecuta en la parte superior de una máquina virtual (?). ¿O es JIT cumplido con el código máquina nativo?¿Compilación o complicación del código .NET?

Q2) Si el segundo es verdadero (JIT cumplió con el código de máquina nativo), ¿dónde se encuentra el sandbox .NET bajo el que se ejecuta el código?

Q3) Además, ¿por qué el código se compiló a IL en primer lugar. ¿Por qué no simplemente compilar a código máquina nativo todo el tiempo? Hay una herramienta de MS de esto llamada ngen pero ¿por qué es eso opcional?

+0

Una buena respuesta a [¿Por qué IL?] (Http://blogs.msdn.com/b/ericlippert/archive/2011/11/18/why-il.aspx) por alguien que trabaja en el Compilador de C# –

Respuesta

12

El IL está JIT (JIT = Just In Time) compilado en código máquina nativo a medida que se ejecuta el proceso.

El uso de una capa de máquina virtual permite que .NET se comporte de manera uniforme en todas las plataformas (por ejemplo, un int es siempre 32 bits independientemente de si se está ejecutando en una máquina de 32 o 64 bits; el caso con C++).

La compilación JIT permite que las optimizaciones se adapten dinámicamente al código mientras se ejecuta (por ejemplo, aplicar optimizaciones más agresivas a los bits de código que se llaman con frecuencia, o hacer uso de las instrucciones de hardware disponibles en la máquina específica como SSE2). Qué hacer con un compilador estático.

+0

también permite optimizaciones basadas en el entorno en el que se encuentra el CLR. –

0

1. C# se compila en CIL (o IL) porque comparte una plataforma con el resto de los lenguajes .NET (por lo que puede escribir una DLL en C# y usarla en VB.NET o F # sin problemas). El CLR luego JAT Compilará el código en Native Machine Code.

.NET también se puede ejecutar en múltiples plataformas (Mono on * NIX y OS X). Si C# compiló al código nativo, esto no sería tan fácil.

2. No hay recinto de seguridad.

3. cubiertos en la respuesta a # 1

0

A1) De esta manera es independiente de la plataforma (Windows, Linux, Mac) y también puede utilizar optimizaciones específicas para el hardware actual. Cuando se compila JIT es para código de máquina.

A2) El framework completo (el .NET framework) es todo sandbox, por lo que todas las llamadas que realice a través de su aplicación pasarán por el entorno limitado de .NET framework.

A3) Como en la respuesta 1, permite que el binario .NET funcione en diferentes plataformas y realice optimizaciones específicas en la máquina del cliente sobre la marcha.

1

Puede usar NGEN para crear versiones nativas de sus ensamblajes .NET. Hacer esto significa que el JIT no tiene que hacer esto en tiempo de ejecución.

.NET se compila primero en IL y luego en nativo ya que el JIT se diseñó para optimizar el código IL para la CPU actual bajo la cual se ejecuta el código.

. El código .NET está compilado en IL por compatibilidad. Como puede crear código usando C#, VB.NET, etc., el JIT necesita un conjunto de instrucciones común (IL) para compilar a código nativo. Si el JIT debe conocer los idiomas, entonces el JIT deberá actualizarse cuando se publique un nuevo lenguaje .NET.

No estoy seguro acerca de la pregunta de sandbox, mi mejor estimación es que una aplicación .NET se ejecuta con 3 dominios de aplicación.Un dominio contiene los tiempos de ejecución .NET (mscorlib, system.dll, etc.), otro dominio contiene su código .NET, y no recuerdo para qué sirve el otro dominio. Salida http://my.safaribooksonline.com/9780321584090

0

El código .Net compilado se convierte en IL, que es un lenguaje intermedio exactamente del mismo modo que el código objeto de Javas. Sí, es posible generar código de máquina nativo usando la herramienta NGen. NGen vincula la imagen nativa resultante a la máquina, por lo que copiar el binario ngen'd a un sistema diferente no produciría los resultados esperados. La compilación del código intermedio permite tomar decisiones de tiempo de ejecución que de otro modo no se pueden (fácilmente) con un lenguaje de tipo estático como C++, también permite el funcionamiento del código en diferentes arquitecturas de hardware porque el código se vuelve descriptivo en el Tenga en cuenta que también describe la intención de lo que debería suceder en un bit (por ejemplo, 32 o 64), forma de diagnóstico, en oposición al código específico de la máquina que solo funciona en sistemas de 32 bits o de 64 bits, pero no en ambos.

Además, NGen es opcional porque como dije, une el binario al sistema, puede ser útil cuando se necesita el rendimiento del código máquina compilado con la flexibilidad de un lenguaje de tipado dinámico y se sabe que el binario ganó ' Te muevo a un sistema al que no está obligado.

3

A1) JIT compila a código máquina nativo

A2) En .NET no existe un término tal como caja de arena. Hay AppDomains en su lugar. Y que se ejecuta como parte de CLR (es decir, como parte del proceso ejecutable)

inconvenientes A3) NGEN de Jeffrey Richter:

  • archivos NGen'd pueden perder la sincronización. Cuando el CLR carga un archivo NGen'd, compara un número de características sobre el código previamente compilado y el entorno de ejecución actual . Si alguna de las características no coincide, el archivo NGen'd no puede ser utilizado, y en su lugar se utiliza el proceso de compilación JIT normal.

  • Inferior Load-Time Performance (Rebasing/Binding). Los archivos de ensamblaje son archivos estándar de Windows PE y, como tales, cada uno contiene una dirección base preferida. Muchos desarrolladores de Windows están familiarizados con los problemas que rodean las direcciones base y el rebase. Cuando el código de compilación JIT, estos problemas no son una preocupación porque las referencias de direcciones de memoria correctas se calculan en tiempo de ejecución.

  • Inferior Execution-Time Performance. Al compilar el código, NGen no puede hacer tantas suposiciones sobre el entorno de ejecución como el compilador JIT. Esto hace que NGen.exe produzca un código inferior. Por ejemplo, NGen no optimizará el uso de ciertas instrucciones de la CPU ; agrega indirecciones para el acceso de campo estático porque la dirección real de los campos estáticos no se conoce hasta el tiempo de ejecución. NGen inserta código para llamar a los constructores de la clase en todas partes porque no conoce el orden en que se ejecutará el código y si ya se ha llamado a un constructor de clase.

Cuestiones relacionadas