Pergunta

Como uma espécie de acompanhamento para a questão chamado entre MSIL e Java bytecode? , o que é as (grandes) diferenças ou semelhanças na forma como o Java Virtual Machine funciona versus como o .NET Framework Common Language Runtime (CLR) funciona?

Além disso, é o .NET framework CLR uma "máquina virtual" ou ele não tem os atributos de uma máquina virtual?

Foi útil?

Solução

Há uma série de semelhanças entre ambas as implementações (e na minha opinião: sim, ambos são "máquinas virtuais").

Por um lado, eles são ambos VM, sem nenhuma noção de "registros" como nós estamos acostumados a ver em um processador moderno como o x86 ou PowerPC baseado em pilha. A avaliação de todas as expressões ((1 + 1) / 2) é realizada empurrando operandos na "pilha" e, em seguida, avançar esses operandos da pilha sempre que uma instrução (add, dividir, etc) precisa consumir esses operandos. Cada instrução põe seus resultados de volta para a pilha.

É uma forma conveniente para implementar uma máquina virtual, porque praticamente todos os CPU no mundo tem uma pilha, mas o número de registros é muitas vezes diferente (e alguns registros são para fins especiais, e cada instrução espera que seus operandos em diferentes registros, etc).

Então, se você estiver indo para modelar uma máquina abstrata, um modelo puramente baseado em pilha é uma boa maneira muito para ir.

Claro, máquinas reais não funcionam dessa maneira. Portanto, o compilador JIT é responsável por executar "enregistration" das operações de bytecode, essencialmente agendar os registos da CPU reais para conter operandos e os resultados sempre que possível.

Então, eu acho que é um dos maiores semelhanças entre o CLR eo JVM.

Como para as diferenças ...

Uma diferença interessante entre as duas implementações é que o CLR inclui instruções para a criação de tipos genéricos, em seguida, para a aplicação de especializações paramétricos para esses tipos. Assim, em tempo de execução, o CLR considera um List para ser um tipo completamente diferente de um List .

Nos bastidores, ele usa o mesmo MSIL para todas as especializações de tipo de referência (para um List usa a mesma implementação como um List , com diferentes tipo de-lança nos limites da API), mas cada valor -tipo usa sua própria implementação exclusivo (List gera código completamente diferente de List ).

Em Java, tipos genéricos são um um truque puramente compilador. A JVM não tem noção de que as classes têm tipo-argumentos, e é incapaz de executar especializações paramétricos em tempo de execução.

De uma perspectiva prática, isso significa que você não pode sobrecarregar os métodos Java em tipos genéricos. Você não pode ter dois métodos diferentes, com o mesmo nome, diferindo apenas em se aceitam um List ou List . Claro, desde que o CLR sabe sobre tipos paramétricos, que não tem nenhum problema métodos sobrecarregados em especializações de tipo genérico manipulação.

Em uma base dia-a-dia, que é a diferença que noto mais entre o CLR eo JVM.

Outras diferenças importantes incluem:

  • O CLR tem encerramentos (implementado como C # delegados). O JVM faz fechamentos de apoio apenas desde Java 8.

  • O CLR tem co-rotinas (implementados com a palavra-chave # C 'rendimento'). A JVM não.

  • O CLR permite que o código de utilizador para definir novo valor tipos (estruturas), ao passo que a JVM fornece um conjunto fixo de tipos de valor (byte, curto, int, longo, flutuador, duplo, carvão animal, booleanas) e só permite usuários para definir nova referência-tipos (classes).

  • A CLR fornece suporte para declarar e manipular ponteiros. Isto é especialmente interessante porque tanto a JVM e os rigorosos implementações coletor de compactação de lixo geracional CLR empregar como sua estratégia de gerenciamento de memória. Em circunstâncias normais, um rigoroso compactação GC tem um tempo muito difícil com ponteiros, porque quando você move um valor de um local de memória para outro, todos os ponteiros (e ponteiros para ponteiros) tornar-se inválido. Mas o CLR fornece um mecanismo de "pinagem" de modo que os desenvolvedores podem declarar um bloco de código dentro do qual o CLR não é permitido para mover alguns ponteiros. É muito conveniente.

  • A maior unidade de código na JVM é ou um 'pacote' como evidenciado pela palavra-chave 'protegido' ou, sem dúvida, um JAR (ou seja Java Arccolmeia) como evidenciado por ser capaz de especificar um frasco no classpath e tê-lo tratado como uma pasta de código. No CLR, as classes são agregadas em 'conjuntos', e o CLR fornece lógica para raciocinar sobre e manipulação de conjuntos (os quais são carregados em "AppDomains", fornecendo caixas de areia sub-aplicação de nível para atribuição de memória e a execução de código).

  • O formato CLR bytecode (composto por instruções MSIL e metadados) tem menos tipos de instrução do que a JVM. Na JVM, cada operação única (adicionar dois valores int, adicionar dois valores float, etc) tem a sua própria instrução único. No CLR, todas as instruções MSIL são polimórficos (adicionar dois valores) e o compilador JIT é responsável por determinar os tipos de operandos e criar o código de máquina apropriada. Eu não sei qual é a preferência estratégia, no entanto. Ambos têm vantagens e desvantagens. O compilador JIT HotSpot, para a JVM, pode usar um mecanismo mais simples de geração de código (não precisa determinar operando tipos, porque já está codificado na instrução), mas isso significa que ele precisa de um formato de bytecode mais complexo, com mais tipos de instrução.

Estou usando Java (e admirando a JVM) por cerca de dez anos.

Mas, na minha opinião, o CLR é agora a implementação superior, em quase todos os sentidos.

Outras dicas

Sua primeira pergunta é comparar a JVM com o .NET Framework - Eu suponho que você realmente significou para comparar com o CLR vez. Se assim for, eu acho que você poderia escrever um pequeno livro sobre este ( EDIT: parece com Benji já tem :-)

Uma diferença importante é que o CLR é projetado para ser uma arquitetura de linguagem neutra, ao contrário do JVM.

Outra diferença importante é que o CLR foi projetado especificamente para permitir um alto nível de interoperabilidade com código nativo. Isto significa que o CLR deve gerenciar a confiabilidade e segurança quando a memória nativa é acessado e modificado, e também gerenciar triagem entre estruturas de dados baseados em CLR e estruturas de dados nativas.

Para responder à sua segunda pergunta, o termo “máquina virtual” é um termo mais antigo do mundo do hardware (por exemplo, a virtualização do 360 na década de 1960 da IBM) que é utilizado para significar uma emulação da máquina subjacente software / hardware para realizar a mesmo tipo de material que VMWare faz.

O CLR é muitas vezes referido como um "mecanismo de execução". Neste contexto, que é uma implementação de uma máquina IL em cima de um x86. Este é também o que a JVM faz, embora você pode argumentar que há uma diferença importante entre bytecodes polimórficas do CLR e bytecodes digitadas do JVM.

Portanto, a resposta pedante à sua segunda pergunta é "não". Mas ele realmente se resume a forma como você definir esses dois termos.

EDIT: Mais uma diferença entre o JVM e CLR é que a JVM (versão 6) é muito relutantes para liberar alocados volta de memória para o sistema operacional, mesmo quando ele pode.

Por exemplo, digamos que um processo JVM começa e aloca 25 MB de memória do sistema operacional inicialmente. O código do aplicativo, em seguida, tenta atribuições que exigem um 50 MB adicional. O JVM irá alocar um adicional de 50 MB a partir do sistema operacional. Uma vez que o código do aplicativo parou de usar essa memória, é coleta de lixo eo tamanho de heap JVM irá diminuir. No entanto, a JVM só irá liberar a memória do sistema operacional alocados sob certas circunstâncias muito específicas . Caso contrário, para o resto da vida processo que a memória permanecerá alocado.

O CLR, por outro lado, libera alocados volta de memória para o sistema operacional se ele não é mais necessário. No exemplo acima, o CLR teria liberado a memória uma vez que a pilha tinha diminuído.

Mais detalhes sobre as diferenças podem ser encontradas na partir de várias fontes acadêmicas e privadas. Uma vez bom exemplo é CLR Projeto Escolhas .

Alguns exemplos específicos incluem:

  • Alguns opperands de baixo nível são digitadas como "adicionar dois ints" onde, como CLR usa um operando polimórfico. (Ou seja fadd / iadd / Ladd vs basta adicionar)
  • Atualmente, a JVM faz perfis de tempo de execução mais agressivo e otimização (ou seja Hotspot). CLR atualmente faz otimizações JIT, mas não otimização de tempo de execução (ou seja, substituir o código enquanto estiver em execução).
  • CLR faz nem métodos em linha virtuais, JVM faz ...
  • Suporte para tipos de valor no CLR além de apenas os "primitivos".

O CLR ea JVM são ambas as máquinas virtuais.

O .NET Framework e do Java Runtime Environment são a agregação do respectivo VMs e suas bibliotecas. Sem bibliotecas as VMs são bastante inútil.

Não é uma máquina virtual, a NET Framework compila as montagens em binário nativo no momento da primeira execução:

Em computação, just-in-time compilação (JIT), também conhecida como tradução dinâmica, é uma técnica para melhorar o desempenho de tempo de execução de um programa de computador. JIT baseia-se em duas ideias anteriores em ambientes run-time: Compilação bytecode e compilação dinâmica. Ela converte o código em tempo de execução antes de executar nativamente, por exemplo código de bytes para o código de máquina nativo. A melhoria do desempenho ao longo intérpretes origina de cache os resultados de traduzir blocos de código, e não simplesmente reavaliando cada linha ou operando cada vez que é exigida (ver linguagem interpretada). Ele também tem vantagens sobre estaticamente compilar o código em tempo de desenvolvimento, pois pode recompilar o código se este for encontrado para ser vantajoso, e pode ser capaz de fazer valer garantias de segurança. Assim JIT pode combinar algumas das vantagens de interpretação e estático (antes-do-tempo) compilação.

Vários ambientes de execução modernos, como .NET Framework da Microsoft, a maioria das implementações de Java e, mais recentemente ActionScript 3, dependem de compilação JIT para a execução de código de alta velocidade.

Fonte: http://en.wikipedia.org/wiki/Just-in -time_compilation

Adicionando-se framework .NET contém uma máquina virtual, assim como o Java.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top