Hi, I heard many times that Java implemments JIT(just-in-time) compilation, and its bytecodes which are portable across platforms get "interpreted" by JVM. However, I don't really know what the bytecodes are, and what the JVM actually mean in Java language architecture; I would like to know more about them.
Bytecode is a step between your source code and actual machine code. The JVM is what takes the bytecode and translates it into machine code.
JIT refers to the fact that the JVM does this translation on the fly when the program is executed, rather than in a single step (like in a traditionally compiled/linked language like C or C++)
The point of bytecode is that you get better performance than a strictly interpreted language (like PHP for example) because the bytecode is already partially compiled and optimized. Also, since the bytecode doesn't need to be directly interpreted by the CPU, it doesn't need to be tied to any specific CPU architecture which makes it more portable.
The disadvantage of course is that it will generally be a bit slower than a natively compiled application since the JVM still has to do some work in translating the bytecode to machine code.
When you compile something in Java, the compiler generates bytecode. This is native code for the Java Virtual Machine. The JVM then translates the bytecode to native code for your processor/architecture, this is where the JIT happens. Without JIT, the JVM would translate the program one instruction at a time, which is very slow.
jcyang already provided a link to wikipedia, but this one is a better match to your question:
The Java Compiler compiles Java Source code to class files. The class's methods are translated to Byte Code and the Java virtual machine (JVM) interpretes this byte code. A Just In Time compiler (JIT) may be used to translate the byte code to machine code to speed up execution of class methods.
Bytecode is the JVM equivalent of machine language instructions.
The JVM (Java Virtual Machine) has an instruction set just like a real machine. The name given to this instruction set is Java Bytecode. It is described in the Java Virtual Machine Specification. Other languages are translated into a bytecode before execution, for example ruby and python. Java's bytecode is at a fairly low level while python's is much more high level.
Interpretation and JIT compilation are two different strategies for executing bytecode. Interpretation processes bytecodes one at a time making the changes to the virtual machine state that are encoded in each instruction. JIT compilation translates the bytecode into instructions native to the host platform that carry out equivalent operations.
Interpretation is generally quick to start but slow during execution, while JIT has more startup overhead but runs quicker afterwards. Modern JVMs use a combination of interpretation and JIT techniques to get the benefit of both. The bytecode is first interpreted while the JIT is translating it in the background. Once the JIT compilation is complete, the JVM switches to using that code instead of the interpreter. Sometimes JIT compilation can produce better results than the ahead-of-time compilation used for C and C++ because it is more dynamic. The JVM can keep track of how often code is called and what they typical paths through the code are and use this information to generate more efficient code while the program is running. The JVM can switch to this new code just like when it initially switches from the interpreter to the JIT code.
Just like there are other languages that compile to native code, like C, C++, Fortran; there are compilers for other languages that output JVM bytecode. One example is the scala language. I believe that groovy and jruby can also convert to java bytecode.
http://www.artima.com/insidejvm/ed2/introarch2.html. I recommend reading whole book.