vedila così: in java è la JVM che interfaccia in tempo reale (leggi "traduce") il bytecode (class) universale per la particolare architettura su cui gira. Insomma Bytecode unico per tutte le piattaforme ma JVM specifica per ogni piattaforma.
Nel C invece la compilazione genera direttamente codice interpretabile dalla singola macchina e quindi, una volta compilato, non può girare su altre architetture, ma non ha bisogno di un ambiente runtime come un Virtual Machine.
codice:
|-------JVM windows-->esecuzione w32
sorgente java->class->------- JVM linux------>esecuzione linux
|-------JVM OSX------>esecuzione 0SX
|-------JVM symbian-->esecuzione symbian
|-------compilatore+linker windows-->esecuzione w32
sorgente C->--------compilatore+linker linux----->esecuzione linux
|-------compilatore+linker OSX------>esecuzione 0SX