Eu acho que há uma distinção a ser feita, no entanto, não é necessariamente entre "Compilado" e "Gerenciado". Estes não são opostos; um idioma pode ser compilado e não gerenciado, ou interpretado (não compilado) e gerenciado, ou ambos, ou mesmo nenhum.
Uma linguagem "compilada" é simplesmente aquela em que existe uma etapa que transforma o código fonte gravado pelo desenvolvedor em um "bytecode" mais regular, que é o que é executado pela máquina. A "máquina" pode ser o processador real ou uma "máquina virtual" que executa operações adicionais nos códigos de bytes para convertê-los em instruções de máquina "nativas". O antônimo de uma linguagem "compilada" é uma linguagem "interpretada", na qual o código-fonte é transformado em instruções de bytecode no tempo de execução, linha por linha à medida que são executadas, sem uma etapa de compilação. Um híbrido entre eles é "jitting", de "JIT" (Just In Time), que geralmente é interpretado como uma etapa única pela máquina executora;
Uma linguagem "gerenciada" é uma linguagem projetada para produzir programas consumidos em um ambiente de tempo de execução específico, que quase sempre inclui um intérprete de bytecode; uma "máquina virtual" que pega o código do programa e executa alguma transformação adicional à máquina ou ao ambiente. O ambiente também pode incluir gerenciamento de memória, como um "coletor de lixo" e outros recursos de "segurança" destinados a manter o programa operando dentro de sua "caixa de areia" de espaço e ferramentas, no entanto, esses recursos não são o único domínio dos tempos de execução "gerenciados" . Praticamente todas as linguagens interpretadas podem ser consideradas gerenciadas, porque exigem que o intérprete esteja executando sob as linhas do código do "usuário" sendo executado. Além disso, as linguagens JVM e .NET (Java, Scala, C #, VB, F #, IronWhatever) são compilados em uma linguagem intermediária ou IL, que é superficialmente semelhante em forma e função a uma linguagem assembly binária, mas não adere 100% a nenhum conjunto de instruções "nativo". Essas instruções são executadas pela JVM ou pelo CLR do .NET, que as converte efetivamente em instruções binárias nativas específicas da arquitetura da CPU e / ou SO da máquina.
Portanto, os idiomas geralmente podem ser descritos como "compilados" ou "interpretados" e como "não gerenciados" (ou "nativos") e "gerenciados". Existem idiomas que podem ser descritos como qualquer combinação destes, exceto o "nativo interpretado" possível (o que seria verdadeiro apenas para os códigos de operação hexadecimais escritos à mão, onde o que é escrito pelo desenvolvedor é o que é executado); se você considerar a camada de interpretação como um "tempo de execução" (que é fácil de argumentar e difícil de argumentar), todas as linguagens interpretadas são "gerenciadas".
Se você quer ser técnico, quase todos os programas direcionados para um sistema operacional multitarefa hoje em dia são "gerenciados"; o sistema operacional criará uma "máquina virtual" para cada programa em execução, na qual o programa pensa (ou pelo menos não precisa saber de outra forma) que é a única coisa em execução. O código pode fazer chamadas dentro de si e para outras bibliotecas referenciadas como se esse programa fosse a única coisa carregada na memória; Da mesma forma, as chamadas para alocar RAM e outra memória superior para armazenar e manipular dados e dispositivos de controle são codificadas como se toda a arquitetura de memória estivesse disponível. A VM (e o sistema operacional por trás dela) converte vários ponteiros de memória para o local real do programa, seus dados e conectores aos drivers de dispositivo etc. Isso geralmente é feito aplicando um deslocamento de memória (cada VM recebe um bloco de 2 GB ou qualquer memória, começando no endereço X, que o programa pode tratar como se esse X fosse o endereço 0) e, como tal, é muito barato, mas há outras coisas pelas quais o kernel do sistema operacional é responsável, como agendamento de processos e comunicação entre processos, que são mais difícil de gerenciar. No entanto, esse padrão básico geralmente não é considerado "gerenciado", pois o programa não precisa saber que está sendo executado por uma máquina virtual e ainda é frequentemente responsável por manter a memória alocada "limpa". Um programa que foi projetado para ser executado na linha de comando do MS-DOS pode ser executado em sistemas operacionais Windows mais recentes que nem sequer têm o ambiente do MS-DOS embaixo deles; o programa recebe um ambiente de "console virtual" e, desde que não tente sair dessa "caixa de areia"