Banal initialization sequences had been a curse on the java runtime. A constant amount of time it takes for booting up the JVM, creating and initializing the vital organs of the virtual machine along with the loading of the kernel classes (such as java/lang/*) used to degrade the startup performance of enterprise applications at large, irrespective of the enterprise and characteristics of the resident application.
While thinking of solutions to reduce startup time, an obvious thought is about dynamic compiler such as JIT, which can intelligently profile the java bytecodes which get executed in this early phase of the JVM life-cycle, and perform native translations on those bytecodes specially, overriding the usual compilation qualifications and policies.
But this technique has its own drawback in that, when you go for optimally compiling the methods which impart in the startup, the compilation effort adds its own overhead to the startup, and the end result is a worsened performance.
Reflect upon this new problem at hand and you get the next obvious solution - fall back to the static compilation for these methods. One can fancy about statically compiling the entire rt.jar (or core.jar) in the target host, before JVM starts, and just use the compiled code at runtime, much in the same manner as the statically compiled executables and libraries.
But static compilation does not fare well with java: Apart from loosing the platform independence (can be solved by compiling in the target host), several powerful optimizations such as virtual method inlining cannot be properly performed because many information which dynamic compiler can obtain at runtime to positively influence the optimization, will be missing at the static compilation time.
AoT is an attempt to address the startup delay in applications, by compiling the method at such an optimization plan where all the statically computable information are utilized up-to the best possible extent, still providing a better performance than the interpreted bytecodes. Specially useful in clustered environments where the methods which are compiled at AoT level in one JVM, can be shared and re-used by other JVMs which take life at later point of time, and boost their startup drastically.