Functional characteristics in general:
The JIT compiler translates bytecode into native machine code at runtime. This compilation process (also known as dynamic translation) is executed only once, and creates a link between the bytecode and the corresponding compiled code. The purpose of this process is to increase the speed in which to run Java programs.
A JIT compiler is based on two concepts in the recent run-time environments: bytecode compilation and dynamic compilation.
In a system for compiling bytecode as Perl, GNU, Java, etc.. The source code is translated into an intermediate representation known as bytecode. The bytecode is then interpreted or executed in a virtual machine (VM).
In a JIT environment, the first phase is the compilation of bytecodes, which transforms the source code in a portable and optimized intermediate representation, called bytecode. Subsequently, the byte code is installed on the target system. When the code is executed, the compiler execution environment translates into native machine code. The translation into machine code can occur for files or function: the functions can only be completed when they are to be executed, hence the name "just-in-time
The just-in-time compilation allows a good compromise between execution speed and code portability. During the compilation of the bytecode is executed most of the "heavy work", ie all those operations that require a long time to run, as the syntactic and semantic analysis of source code and a first phase of optimization, the compilation from bytecode to native code is much faster.
In particular for android devices:
Here some information on the operation related to android
Essentially, Java is usually translated from source to Java bytecode (an intermediate step between Java itself & processor specific machine code) when the app is compiled. When it is executed, this bytecode has to be interpreted into machine code. What JIT does is cache the results of such interpretation, so that, for example, if a particular section of bytecode is executed multiple times, it will only have to be interpreted that first time. JIT for Java has been around for a good while.
Android uses their own special Java Virtual Machine, which we hear of often - the Dalvik Virtual Machine. This works on similar principles to a typical JVM, but it produces a type of intermediate bytecode that is optimised for execution on devices with limited resources. This code, incidentally, is called a Dalvik Executable, which explains all the .dex sufficies in Android.
As this Dalvik Virtual Machine is relatively new, the further refinement of just in time compilation for it is only now reaching a stage where it's production ready - or at least hopefully will be soon. All pretty exciting as it can boost performance by around 200-300%