Natürlich gibt es die. Der JIT weiß, welche Codepfade wie oft durchlaufen werden und kann entsprechend optimieren (geht mit PGO für C/C++ auch, zumindest wenn das halbwegs konstant ist; ist es aber üblicherweise). Der JIT weiß, auf welcher CPU er läuft. Z.B. kann er auf einem Uniprocessor-System teure atomic instructions weglassen. Nachdem's kaum mehr Uniprocessor-System gibt, wird das zwar weniger relevant, aber maschinenspezifische Optimierung kann immer noch einiges bringen. Der JIT kann virtual function calls durch statische ersetzen (und inlinen), wenn keine Klassen geladen sind, die diese Methoden überschreiben können. Und es gibt sicher noch viele mehr. Aber vor allem das mit dem Inlining von virtuellen Funktionen ist in Java ein wesentlicher Performance-Faktor.
ahead-of-time compiler haben nochdazu probleme mit dynamic class loading, was für JIT compiler klarerweise gar kein problem ist. ahead-of-time compiler für java haben sich vor allem im embedded bereich durchgesetzt, da lebt man halt mit der einschränkung.
nur so nebenbei: java ist viel schneller als die meisten denken, trotz JIT compilation. ob man dadurch zum java-fan wird, ist jedem selbst überlassen