Programas Java não são traduzidos para a linguagem de máquina, como outras linguagens estaticamente compiladas e sim para uma representação intermediária, chamada de bytecodes.
Os bytecodes são interpretados pela máquina virtual Java (JVM - Java Virtual Machine). Muitas pessoas acreditam que por causa desse processo, o código interpretado Java tem baixo desempenho, mas isso não é verdade. Durante muito tempo esta foi uma afirmação verdadeira. Porém novos avanços têm tornado o compilador dinâmico (a JVM), em muitos casos, mais eficiente que o compilador estático.
Java hoje já possui um desempenho próximo do C++. Isto é possível graças a otimizações como a compilação especulativa, que aproveita o tempo ocioso do processador para pré-compilar bytecode para código nativo. Outros mecanismos ainda mais elaborados como o HotSpot da Sun, que guarda informações disponíveis somente em tempo de execução (ex.: número de usuários, processamento usado, memória disponível), para otimizar o funcionamento da JVM, possibilitando que a JVM vá "aprendendo" e melhorando seu desempenho. Isto é uma realidade tão presente que hoje é fácil encontrar programas corporativos e de missão crítica usando tecnologia Java. No Brasil, por exemplo, a maioria dos Bancos utiliza a tecnologia Java para construir seus home banks, que são acessados por milhares de usuários diariamente. Grandes sítios como o eBay utilizam Java para garantir alto desempenho. E a cada ano Java tem se tornado mais rápido, na medida que se evolui o compilador dinâmico [7][carece de fontes?].
Essa implementação no entanto tem algumas limitações intrínsecas. A pré-compilação exige tempo, o que faz com que programas Java demorem um tempo significativamente maior para começarem a funcionar. Soma-se a isso o tempo de carregamento da máquina virtual. Isso não é um grande problema para programas que rodam em servidores e que deveriam ser inicializados apenas uma vez. No entanto isso pode ser bastante indesejável para computadores pessoais onde o usuário deseja que o programa rode logo depois de abri-lo. A próxima versão da máquina virtual produzida pela Sun promete novos recursos que irão minimizar este fato.1
O Java ainda possui uma outra desvantagem considerável em programas que usam bastante processamento numérico. O padrão Java tem uma especificação rígida de como devem funcionar os tipos numéricos. Essa especificação não condiz com a implementação de pontos flutuantes na maioria dos processadores o que faz com que o Java seja significativamente mais lento para estas aplicações quando comparado a outras linguagens.
Os bytecodes produzidos pelos compiladores Java podem ser usados num processo de engenharia reversa para a recuperação do programa-fonte original. Esta é uma característica que atinge em menor grau todas as linguagens compiladas. No entanto já existem hoje tecnologias que "embaralham" e até mesmo criptografam os bytecodes praticamente impedindo a engenharia reversa.
Artigo publicado originalmente em Wikipedia