Ответ 1
И .NET, и Java компилируются в байт-код, это промежуточный язык, который содержит инструкции для виртуальной машины. Это не машинный код, потому что он не может работать непосредственно на физической машине. Вместо этого происходит (по крайней мере, сегодня; в этом отношении у Java более темная история), что во время выполнения запускается компилятор, который точно в срок, переводит инструкции виртуальной машины в собственный код, который затем запускается напрямую. Это дает значительное преимущество в производительности по сравнению только с интерпретацией.
Они немного отличаются в этом отношении. Реализация Oracle Java (Hotspot) использует разумное сочетание интерпретации, измерения и JIT, компилируя только те части, которые интенсивно используются, и интерпретируя иначе. Это должно уменьшить первоначальное влияние JIT-компилятора (который должен запускаться заранее, увеличивая время запуска процесса), и в то же время обеспечивая при этом хорошую производительность. С другой стороны,.NET всегда JIT-компилирует весь используемый код (однако неиспользуемый код не компилируется).
Редактирование (2019): к настоящему времени .NET также имеет многоуровневую компиляцию, где в зависимости от того, какой код выполняется часто, этот код будет дополнительно оптимизирован.
Что касается вопроса, который вы упомянули в своих комментариях: да, CLR и JVM - это платформы, на которых работают такие программы. Виртуальная машина - это тоже машина, просто менее аппаратная. Они оба тесно интегрированы с соответствующей структурой, библиотекой базовых классов для .NET и библиотекой классов Java для Java. Это рамки.