AOT compilation is one way of improving the performance of Java programs and in particular the startup time of the JVM. The JVM executes Java ...
StartHereCourses ▼▲
RESTwithSpring
ThecanonicalreferenceforbuildingaproductiongradeAPIwithSpring.
LearnSpringSecurity ▼▲
THEuniqueSpringSecurityeducationifyou’reworkingwithJavatoday.
LearnSpringSecurityCore
FocusontheCoreofSpringSecurity5
LearnSpringSecurityOAuth
FocusonthenewOAuth2stackinSpringSecurity5
LearnSpring
Fromnoexperiencetoactuallybuildingstuff.
LearnSpringDataJPA
ThefullguidetopersistencewithSpringDataJPA.
Guides ▼▲
Persistence
ThePersistencewithSpringguides
REST
TheguidesonbuildingRESTAPIswithSpring
Security
TheSpringSecurityguides
About ▼▲
FullArchive
Thehighleveloverviewofallthearticlesonthesite.
BaeldungEbooks
DiscoverallofoureBooks
WriteforBaeldung
Becomeawriteronthesite.
AboutBaeldung
AboutBaeldung.
GenericTop
GetstartedwithSpring5andSpringBoot2,throughtheLearnSpringcourse:
>>CHECKOUTTHECOURSE
1.Introduction
Inthisarticle,we'lllookattheJavaAheadofTime(AOT)Compiler,whichisdescribedinJEP-295andwasaddedasanexperimentalfeatureinJava9.
First,we'llseewhatAOTis,andsecond,we'lllookatasimpleexample.Third,we'llseesomerestrictionsofAOT,andlastly,we'lldiscusssomepossibleusecases.
2.WhatIsAheadofTimeCompilation?
AOTcompilationisonewayofimprovingtheperformanceofJavaprogramsandinparticularthestartuptimeoftheJVM.TheJVMexecutesJavabytecodeandcompilesfrequentlyexecutedcodetonativecode.ThisiscalledJust-in-Time(JIT)Compilation.TheJVMdecideswhichcodetoJITcompilebasedonprofilinginformationcollectedduringexecution.
WhilethistechniqueenablestheJVMtoproducehighlyoptimizedcodeandimprovespeakperformance,thestartuptimeislikelynotoptimal,astheexecutedcodeisnotyetJITcompiled.AOTaimstoimprovethisso-called warming-upperiod.ThecompilerusedforAOTisGraal.
Inthisarticle,wewon'tlookatJITandGraalindetail. Pleaserefertoourotherarticlesforanoverviewof performanceimprovementsinJava9and10,aswellasa deepdiveintotheGraalJITCompiler.
3.Example
Forthisexample,we'lluse averysimpleclass,compileit,andseehowtousetheresultinglibrary.
3.1.AOTCompilation
Let'stakeaquicklookatoursampleclass:
publicclassJaotCompilation{
publicstaticvoidmain(String[]argv){
System.out.println(message());
}
publicstaticStringmessage(){
return"TheJAOTcompilersays'Hello'";
}
}
BeforewecanusetheAOTcompiler,weneedtocompiletheclasswiththeJavacompiler:
javacJaotCompilation.java
Wethenpasstheresulting JaotCompilation.class tothe AOTcompiler,whichislocatedinthesamedirectoryasthestandardJavacompiler:
jaotc--outputjaotCompilation.soJaotCompilation.class
Thisproducesthelibrary jaotCompilation.sointhecurrentdirectory.
3.2.RunningtheProgram
Wecanthenexecutethe program:
java-XX:AOTLibrary=./jaotCompilation.soJaotCompilation
Theargument-XX:AOTLibraryacceptsarelativeorfullpathtothelibrary.Alternatively,wecancopythelibrarytothelibfolderintheJavahomedirectoryandonlypassthenameofthelibrary.
3.3.VerifyingThattheLibraryIsCalledandUsed
Wecanseethatthelibrarywasindeedloadedbyadding-XX:+PrintAOTasaJVMargument:
java-XX:+PrintAOT-XX:AOTLibrary=./jaotCompilation.soJaotCompilation
Theoutputwilllooklike:
771loaded./jaotCompilation.soaotlibrary
However,thisonlytellsusthatthelibrarywasloaded,butnotthatitwasactuallyused.Bypassingtheargument-verbose,wecan seethatthemethodsinthelibraryareindeedcalled:
java-XX:AOTLibrary=./jaotCompilation.so-verbose-XX:+PrintAOTJaotCompilation
Theoutputwillcontainthelines:
111loaded./jaotCompilation.soaotlibrary
1161aot[1]jaotc.JaotCompilation.()V
1162aot[1]jaotc.JaotCompilation.message()Ljava/lang/String;
1163aot[1]jaotc.JaotCompilation.main([Ljava/lang/String;)V
TheJAOTcompilersays'Hello'
TheAOTcompiledlibrarycontainsaclassfingerprint,whichmustmatchthefingerprintofthe.classfile.
Let'schangethecodeintheclassJaotCompilation.javatoreturnadifferentmessage:
publicstaticStringmessage(){
return"TheJAOTcompilersays'Goodmorning'";
}
IfweexecutetheprogramwithoutAOTcompilingthemodifiedclass:
java-XX:AOTLibrary=./jaotCompilation.so-verbose-XX:+PrintAOTJaotCompilation
Thentheoutputwillcontainonly:
111loaded./jaotCompilation.soaotlibrary
TheJAOTcompilersays'Goodmorning'
Wecanseethatthemethodsinthelibrarywon'tbecalled,asthebytecodeoftheclasshaschanged.Theideabehindthisisthattheprogramwillalwaysproducethesameresult,nomatterifanAOTcompiledlibraryisloadedornot.
4.MoreAOTandJVMArguments
4.1.AOTCompilationofJavaModules
It'salsopossibletoAOTcompileamodule:
jaotc--outputjavaBase.so --modulejava.base
TheresultinglibraryjavaBase.soisabout320MBinsizeandtakessometimetoload.ThesizecanbereducedbyselectingthepackagesandclassestobeAOTcompiled.
We'lllookathowtodothatbelow,however,we'llnotdivedeeplyintoallthedetails.
4.2.SelectiveCompilationwithCompileCommands
TopreventtheAOTcompiledlibraryofaJavamodulefrombecomingtoolarge,wecanaddcompilecommandstolimitthescopeofwhatgetsAOTcompiled.Thesecommandsneedtobeinatextfile –inourexample,we'llusethefile complileCommands.txt:
compileOnlyjava.lang.*
Then,weaddittothecompilecommand:
jaotc--outputjavaBaseLang.so--modulejava.base--compile-commandscompileCommands.txt
TheresultinglibrarywillonlycontaintheAOTcompiledclassesinthepackage java.lang.
Togainrealperformanceimprovement,weneedtofindoutwhichclassesareinvokedduringthewarm-upoftheJVM.
ThiscanbeachievedbyaddingseveralJVMarguments:
java-XX:+UnlockDiagnosticVMOptions-XX:+LogTouchedMethods-XX:+PrintTouchedMethodsAtExitJaotCompilation
Inthisarticle,wewon'tdivedeeperintothistechnique.
4.3.AOTCompilationofaSingleClass
Wecancompileasingleclasswiththeargument–class-name:
jaotc--outputjavaBaseString.so--class-namejava.lang.String
TheresultinglibrarywillonlycontaintheclassString.
4.4.CompileforTiered
Bydefault,theAOTcompiledcodewillalwaysbeused,andnoJITcompilationwillhappenfortheclassesincludedinthelibrary.Ifwewanttoincludetheprofilinginformationinthelibrary,wecanaddtheargument compile-for-tiered:
jaotc--outputjaotCompilation.so--compile-for-tieredJaotCompilation.class
Thepre-compiledcodeinthelibrarywillbeuseduntilthebytecode becomeseligibleforJITcompilation.
5.PossibleUseCasesforAOTCompilation
OneusecaseforAOTisshortrunningprograms,whichfinishexecutionbeforeanyJITcompilationoccurs.
Anotherusecaseisembeddedenvironments,whereJITisn'tpossible.
Atthispoint,wealsoneedtonotethattheAOTcompiledlibrarycanonlybeloadedfromaJavaclasswithidenticalbytecode,thusitcannotbeloadedviaJNI.
6.AOTandAmazonLambda
ApossibleusecaseforAOT-compiledcodeisshort-livedlambdafunctionswhereshortstartuptimeisimportant.Inthissection,we'lllookathowwecanrunAOTcompiledJavacodeonAWSLambda.
UsingAOTcompilationwithAWSLambdarequiresthelibrarytobebuiltonanoperatingsystemthatiscompatiblewiththeoperatingsystemusedonAWS.Atthetimeofwriting,thisisAmazonLinux2.
Furthermore,theJavaversionneedstomatch.AWSprovidestheAmazonCorrettoJava11JVM.Inordertohaveanenvironmenttocompileourlibrary,we'llinstallAmazonLinux2andAmazonCorrettoinDocker.
Wewon'tdiscussallthedetailsofusingDockerandAWSLambdabutonlyoutlinethemostimportantsteps.FormoreinformationonhowtouseDocker,pleaserefertoitsofficialdocumentationhere.
FormoredetailsaboutcreatingaLambdafunctionwithJava,youcanhavealookatourarticleAWSLambdaWithJava.
6.1.ConfigurationofOurDevelopmentEnvironment
First,weneedtopulltheDockerimageforAmazonLinux2andinstallAmazonCorretto:
#downloadAmazonLinux
dockerpullamazonlinux
#insidetheDockercontainer,installAmazonCorretto
yuminstalljava-11-amazon-corretto
#someadditionallibrariesneededforjaotc
yuminstallbinutils.x86_64
6.2.CompiletheClassandLibrary
InsideourDockercontainer,weexecutethefollowingcommands:
#createfolderaot
mkdiraot
cdaot
mkdirjaotc
cdjaotc
Thenameofthefolderisonlyanexampleandcan,ofcourse,beanyothername.
packagejaotc;
publicclassJaotCompilation{
publicstaticintmessage(intinput){
returninput*2;
}
}
Thenextstepistocompiletheclassandlibrary:
javacJaotCompilation.java
cd..
jaotc-J-XX:+UseSerialGC--outputjaotCompilation.sojaotc/JaotCompilation.class
Here,it'simportanttousethesamegarbagecollectorasisusedonAWS.IfourlibrarycannotbeloadedonAWSLambda,wemightwanttocheckwhichgarbagecollectorisactuallyusedwiththefollowingcommand:
java-XX:+PrintCommandLineFlags-version
Now,wecancreateazipfilethatcontainsourlibraryandclassfile:
zip-rjaot.zipjaotCompilation.sojaotc/
6.3.ConfigureAWSLambda
ThelaststepistologintotheAWSLamdaconsole,uploadthezipfileandconfigureoutLambdawiththefollowingparameters:
Runtime:Java11
Handler:jaotc.JaotCompilation::message
Furthermore,weneedtocreateanenvironmentvariablewiththenameJAVA_TOOL_OPTIONSandsetitsvalueto:
-XX:+UnlockExperimentalVMOptions-XX:+PrintAOT-XX:AOTLibrary=./jaotCompilation.so
ThisvariableletsuspassparameterstotheJVM.
ThelaststepistoconfiguretheinputforourLambda.ThedefaultisaJSONinput,whichcannotbepassedtoourfunction,thereforeweneedtosetittoaStringwhichcontainsaninteger,e.g.“1”.
Finally,wecanexecuteourLambdafunctionandshouldseeinthelogthatourAOTcompiledlibrarywasloaded:
571loaded./jaotCompilation.soaotlibrary
7.Conclusion
Inthisarticle,wesawhowtoAOTcompileJavaclassesandmodules.Asthisisstillanexperimentalfeature, theAOTcompilerisn'tpartofalldistributions.Realexamplesarestillraretofind,anditwillbeuptotheJavacommunitytofindthebestusecasesforapplyingAOT.
AllthecodesnippetsinthisarticlecanbefoundinourGitHubrepository.
Genericbottom
GetstartedwithSpring5andSpringBoot2,throughtheLearnSpringcourse:
>>CHECKOUTTHECOURSE
Genericfooterbanner
LearningtobuildyourAPIwithSpring?
DownloadtheE-book
2Comments
Oldest
Newest
InlineFeedbacks
Viewallcomments
ViewComments
LoadMoreComments
Commentsareclosedonthisarticle!
Genericsidebarbanner
BuildingaRESTAPIwithSpring5?
DownloadtheE-book
wpDiscuzInsert