Upload
anonrj
View
14
Download
0
Embed Size (px)
DESCRIPTION
Manual de JVM
Citation preview
1. Introduction2. FalandoumpoucosobreJVM3. Sequerespreverofuturo,estudaopassado
i. HistóricodaJVMi. JDKAlphaeBeta(1995)ii. JDK1.1(19defevereirode1997)iii. J2SE1.2(8dedezembrode1998)iv. J2SE1.3(8demaiode2000)v. J2SE1.4(6defevereirode2002)vi. J2SE5.0(30desetembrode2004)vii. JavaSE6(11dedezembrode2006)viii. JavaSE7(28dejulhode2011)ix. JavaSE8(18demarçode2014)
4. FuncionamentobásicodaJVM5. RegistradoresdaJVM
i. ProgramCounterii. JavaStack(Javavirtualmachinestack)
i. StackFrame)i. Stackvariablesii. StackOperandiii. FrameData
iii. NativeMethodStacksiv. MethodAreav. Vendoosconceitosnapráticavi. HeapSpacevii. Cachedecódigo
i. JustInTime(JIT)Compilationviii. Recapitulando
6. ByteCodesi. Carregaresalvarinformaçõesii. Operaçõesaritméticasiii. Conversãodevaloresiv. Criaçãoemanipulaçãodeobjetosv. Instruçõescondicionaisvi. Chamadademétodoseretornodevaloresvii. Classesapóscompilação
7. Ciclodevidadeumaclasse8. GarbageCollector
i. ImplementaçãoSerialii. ImplementaçãoParaleloiii. ImplementaçãoConcurrentiv. ImplementaçãoIncrementalConcurrentv. ImplementaçãoGarbageFirst
9. InterfaceNativaJava10. OprojetoOpenJDK
Tabeladeconteúdos
ImergindonaJVM
2
CertamenteoJavaéatualmenteumadaslinguagensmaisusadaseumadasmaispopularesnomundo,sendoqueoseumaiordiferencialnãoestánalinguagemesimnaJVM(MáquinavirtualJava).Conheçaumpoucomaissobreessemotor,seufuncionamentoesuaarquiteturaparatirarmelhorproveitodelaemsuasaplicações,alémdeconhecerumpoucosobreaimplementaçãodereferênciaeopensourcedaJVM,oOpenJDK.OconteúdodesseE-bookfalarásobre:
osregistradoresdaJVMAinterfacedoJavacomcódigonativo,JNI,presenteemdiversospontosdoJVM,dentreeles,oNIOeGargabeCollector,OfuncionamentobásicodoGarbageCollectorComocompilaroOpenJDKByteCodeeoseufuncionamentoEmuitomais!
ImergindonaJVM
ImergindonaJVM
3Introduction
CertamenteoJavaéatualmenteumadaslinguagensmaisusadasepopularesnomundo,sendoqueoseumaiordiferencialnãoestánalinguagemesimnaJVM,máquinavirtualJava.AJVMvemsendoalvodemuitosestudosepesquisas,afinalconhecerbemaJVMvaigarantiraodesenvolvedorJava,maneirasparatiraromelhorproveitodalinguagemedaplataformaalémdeprogramardemaneiramaiseficientelevandoemconsideraçãotudooqueaJVMpodefazerporeleeajudandoamesmaateajudar.Comesseobjetivoestoucriandoessepequenotexto,ajudaracomunidadebrasileiraaconheceraJVM.
EssematerialéfrutodosmeustrabalhosjuntocomoOpenJDK.AJVMopensourcee,apartirdaversão7,setornouaimplementaçãodereferência.Aocontráriodoquemuitaspessoasimaginam,existemmilhõesdemáquinasvirtuais,dentreasmaispopularesestáaHotSpot(tambémconhecidacomoaJVMdaOracle).OOpenJDKéumprojetoévivocomajudademuitasempresas(Oracle,Intel,RedHat,AMD,Google,etc.),masprincipalmentecomagrandeajudadacomunidade,quedentreasdiversasfrentesdetrabalhoqueexistempodemosdestacaroAdoteoOpenJDKquevisaaevoluçãodaplataformaedoJavaLivre(ajudandonarefatoração,evangelizandosobreoOpenJDK,identificandoecorrigindobugs).
Parafacilitaroentendimentodoleitoressetrabalhofoidivididoemseispartes:
AprimeirafalaráumpoucosobreoJava,fazendoadevidaseparaçãoentrelinguagem,plataformaemáquinavirtualalémdefalarumpoucosobreahistóriadoJavaedasuaevoluçãojuntocomasversões.
EmseguidasefalarásobreofuncionamentobásicodaJVM,faráadistinçãobásicaentreoJavalinguagemedamáquinavirtual,jáqueaúltimaprecisasercompiladaparaquealinguagemsejamultiplataforma,ociclodevidadaJVMedosprocessosemparaleloquenascemcomumaaplicaçãoJava.
SaberaondeficacadainformaçãodentrodaJVMeonomedosseusrespectivosregistradores.Seráoalvodessaterceirapartedotrabalho.SaberáquaisregistradoresserãocompartilhadosportodasasThreadseaquelesquenãoserão,assimnascememorremcomasuarespectivaThread.
Obytecode,alinguagemdaMáquinavirtual,poucoéexplicadosobreela,massãograçasaosseusopcodesqueaJVMémultiplataforma.NessaparteseveráquãodiferenteéoseucódigoemJavaedoprodutogerado,obytecode,alémdaestruturaqueaclasseadquireapósoprocessodecompilação.
AJVMconsisteemumprocessobásicodepegarainformaçãodaclasse,gerarstreamparadentrodaJVM(Naturalmentenamemóriaprincipal)eexecutá-lootornandoemcódigonativo,esseprocessodecarregarumaclasseéfeitaemtempodeexecução,ouseja,sóécarregadaaclasseXnomomentoemqueelaforchamada,nãobastaestarapenasnoimport,casoessaclassetenhaumpaiouimplementeinterfaceselasserãocarregadasantesdessaclasseX.Todaclassepossuiumciclodevidaeconheçaumpoucomaissobreesteciclonapartenúmerocinco.
UmgrandediferencialdaJVMéorecursodegerenciamentoautomáticodamemória,esseprocessoconsistememmatarerecuperarmemóriadeobjetosquenãoestãomaissendoutilizados,esseéopapeldoGarbageCollector.Conheçaumpoucomaissobreasimplementaçõeseemquaissituaçõeselassãomaisaconselhadas.
ParafinalizarserádemonstradaumavisãopráticadoJNIedoprojetoOpenJDKalémdosconceitosdecompilaraJVM.
FalandoumpoucosobreJVM
ImergindonaJVM
4FalandoumpoucosobreJVM
JVM,javavirtualmachineoumáquinavirtualjava,temsuahistóriainciadaem1992.OGreenProjectnaépocaalinguagemeradenominadadeoak.Comopassardotempoamáquinavirtualfoievoluindoeficandocadavezmaiscomplexa.AlinguagemJavapossuiumasintaxesimilaraoC++,elepodeserusadodeváriasmaneiraseéorientadoaobjetosesetornoupopularemconjuntocomaweb.AJVMfuncionacomooalicercedaplataformaJavaficandoresponsávelportratartodasasplataformaseSistemasOperacionaisdemodoindependenteparaalinguagem.AJVMnãoconheceabsolutamentenadadalinguagemJava,apenasoseubytecode,quevemnoformato.class,quesãoasinstruçõesdaJVM(daíapossibilidadedeportaroutraslinguagensparaaJVMjáqueelenãorodaJavaesimobytecode).Esseclasséocódigocompiladoemjavaerepresentaumaclasseouinterfaceemjava.
DoseuinícioatéapresentedataoJavatevediversasversões.EssasmodificaçõessãogerenciadaspeloJCP,JavaCommunityProcess(ocomitêqueregeasmudançasdaplataformajavacomcercade30empresas),apartirdeJSRs,JavaSpecificationRequests,especificaçõesquefornecemtaismodificaçõesemelhorias.AdocumentaçãodalinguagemficanoJSL,JavaLanguageSpecification,documentaçãodaJVMficaJavaVirtualMachineSpecification.
Sequerespreverofuturo,estudaopassado
ImergindonaJVM
5Sequerespreverofuturo,estudaopassado
AntesdesefalardosaspectosdoJava,comolinguagem,plataformaemáquinavirtualéinteressanteconhecerumpoucosobreaevoluçãoqueoJavavemsofrendo.Oprojetonasceuem1995eapartirdestadataveiosofrendoconstanteevoluçãocomajudadeempresasedacomunidade.
HistóricodaJVM
ImergindonaJVM
6HistóricodaJVM
Nasversõesalfasebetassetiveramumamáquinainstável.1.1.2-JDK1.0(23dejaneirode1996)
ComocódigonomeOak,quetambémfoioprimeironomedalinguagem.Naversão1.0.2foilançadoaprimeiraversãoestável.
JDKAlphaeBeta(1995)
ImergindonaJVM
7JDKAlphaeBeta(1995)
GrandesmelhoriaserefatoraçõesnosmodelosdeeventodoAWTInnerclassadicionadoalinguagemJavaBeansJDBCRMIReflectionquesuportavaapenasintrospecçãoapenas,nenhumamodificaçãoemtemporealerapossível.
JDK1.1(19defevereirode1997)
ImergindonaJVM
8JDK1.1(19defevereirode1997)
ComocodinomePlaground.EssaeasoutrasversõesforamdenominadasdeJava2,J2SEJava2Platform,StandardEdition,Houvemodificaçõessignificantesnessaversãotriplicandoocódigopara1520classesem59pacotesincluindo:
Apalavra-chavestrictfpAapidoSwingforamintegradosaoCoreAdicionandooJITcompiladorJavaPlug-inJavaIDL,umaimplementaçãoCORBAIDLparainteroperabilidadeCollectionsframework
J2SE1.2(8dedezembrode1998)
ImergindonaJVM
9J2SE1.2(8dedezembrode1998)
ComocodinomeKestrel,asmodificaçõesmaisimportantesforam:
HotSpotJVMincluído(aJVMHotSpotfoilançadoemabrilde1999paraos1,2J2SEJVM).RMIfoimodificadoparasuportaracompatibilidadeopcionalcomCORBAJavaSoundJavaNamingandDirectoryInterface(JNDI)incluídoembibliotecascentraisJavaPlatformDebuggerArchitecture(ACDP)Sintéticosclassesdeproxy
J2SE1.3(8demaiode2000)
ImergindonaJVM
10J2SE1.3(8demaiode2000)
ComocodinomeMerlin,foiaprimeiraversãoparaaplataformadesenvolvidapeloJCPcomoaJSR59:
Apalavra-chaveassert(JSR41)ExpressõesregularesEncadeamentodeexceçãopermiteumaexceçãodemaiornívelencapsuleumaexceçãodemenornível.SuporteaoProtocolodeinternetversão6(IPv6)ChamadasdeIO(chamadodeNIO)novosInput/Output(JSR51)APIdeloggin(JSR47)APIparalereescreverimagensinformatoscomoJPEDePNGIntegraçãocomoXMLeXSLT(JAXP)naJSR63Novasintegraçõescomextensõesdesegurançaecriptografia(JCE,JSSE,JAAS).JavaWebStartincluído(JSR56).APIdepreferências(java.util.prefs)
J2SE1.4(6defevereirode2002)
ImergindonaJVM
11J2SE1.4(6defevereirode2002)
ComocodinomeTiger,foidesenvolvidanaJSR176,teveseufinaldevidaem8deabrilde2008eoencerramentodosuportedia3denovembrode2009.OTigeradicionousignificantesmelhoriasparaalinguagem:
Generics:(JSR14).Annotations:(JSR175)Autoboxing/unboxing:Conversãoautomáticaentreostiposprimitivoseasclassesencapsuladas(JSR201).Enumerations:(JSR201.)Varargs:foreachloopCorreçõesparaoJavaMemoryModel(QuedefinecomoThreadsinteragematravésdamemória).StaticimportsGeraçãoautomáticadostubparaobjetosRMINovolookandfeelparaoSwingchamadosynthUmpacoteutilitáriodeconcorrência(java.util.concurrent)AclasseScannerClasseScannerparaanalisardadosdeinputstreamsebuffers
J2SE5.0(30desetembrode2004)
ImergindonaJVM
12J2SE5.0(30desetembrode2004)
ComocodinomeMustangue,nessaversãoaSunsubstituionome“J2SE”eremoveuo“.0”donúmerodaversão.EssaversãofoidesenvolvidanaJSR270.
SuportealinguagemdescriptJSR223):UmaAPIGenéricaparaintegraçãocomlinguagensscriptsefoiembutidoaintegraçãocomoMozillaJavaScriptRhino.SuporteaWebServiceatravésdoJAX-WS(JSR224)JDBC4.0(JSR221).JavaCompilerAPI(JSR199):umaAPIparapermitirchamarcompilaçãoprogramandoJAXB2.0MelhoriasnoAnnotations(JSR269)MelhoriasnoGUI,comoSwingWorker,tabelafiltradaeordenadaMelhoriasnaJVMincluindo:sincronizaçãoeotimizaçõesdocompilador,Melhoriasnoalgorismodocoletordelixo.
JavaSE6(11dedezembrode2006)
ImergindonaJVM
13JavaSE6(11dedezembrode2006)
ComocodinomeDolphinpossuiomaiornúmerodeatualizaçãonoJava.Foilançadonodia7deJulhoefoidisponibilizadonodia28dejulhodomesmoano.
DaVinciMachine:SuporteparalinguagensdinâmicasProjetoCoinStringsinswitchAutomaticresourcemanagementintry-statementDiamondSimplifiedvarargsBinaryintegerliteralsNumericliteralsmult-tryNovopacoteutilitáriodeconcorrência:JSR166NIO2:novosbibliotecaparaIO
JavaSE7(28dejulhode2011)
ImergindonaJVM
14JavaSE7(28dejulhode2011)
OJava8foientreguenodia18demarçode2014enessaversãofoiincluídaalgunsrecursosqueantesestavamplanejadosparaoJava7.OsrecursossubmetidosparaessaversãoforambaseadasempropostasdemelhoriasdoJDK,osJEPS.Dentreessasmelhoriaspodemosdestacar:
JSR223,JEP174:ProjetoNashorn,umexecutorruntimedeJavaScript,dessaformaépossívelJavaScriptdentrodaaplicação.EsseprojetotevecomoobjetivoatualizarserosucessordoRhino,usandoInvokeDynamicemvezdereflection.JSR335,JEP126:SuporteparaexpressõeslambdasJSR310,JEP150:DateandTimeAPIJEP122:RemoçãodoPermanentgeneration
JavaSE8(18demarçode2014)
ImergindonaJVM
15JavaSE8(18demarçode2014)
NessecapítulofalaráumpoucodofuncionamentobásicodaJVMalémdasvariáveis.FalaráumpoucodocoraçãodalinguagemJava,asuaJVM.AJVMéresponsávelpelaindependênciaentreasplataformaserodabasicamentedoistiposdeprocessos:
OescritoemjavaquesãogeradosbytecodesOsnativosquesãorealizadosemlinguagenscomooC\C++quesãolinkadasdinamicamenteparaumaplataformaespecífica.
OsmétodosnativossãomuitointeressantesparaobterinformaçõesdoSOsendoutilizadoalémdeusarrecursosdamáquina.EéemfunçãodissoqueapesardealinguagemserRunAnyWhereaJVMnãoé,ouseja,paracadaplataformaexisteumamáquinavirtualespecífica.Issoacontece,porexemplo,parausarrecursosespecíficosdeumamáquina,porexemplo,existemchamadasparacadadiretórioearquivos.
OúnicoeprincipalmotivodaJVMérodaroaplicativo.QuandoseiniciaumaexecuçãoaJVMnasceequandoaaplicaçãoterminaelamorre.ÉcriadoumaJVMparacadaaplicação,ouseja,seexecutartrêsvezesomesmocódigoemuma
FuncionamentobásicodaJVM
ImergindonaJVM
16FuncionamentobásicodaJVM
mesmamáquinaserãoiniciadas3JVMs.PararodarumaaplicaçãobastaquesuaclassepossuaummétodopúblicoeestáticocomonomemainetenhacomoparâmetroumvetordeString.
AoiniciarumaJVMexistemalgunsprocessosquerodamemparaleloseembackgrounseexecutamdiversasoperaçõeseprocessosparamanteraJVMsempredisponível:
OsTimersquesãoresponsáveispeloseventosqueacontecemperiodicamente,porexemplo,interrupções,elessãousadosparaorganizarosprocessosqueacontecemcontinuamente.OsprocessosdoGarbageCollectoréresponsávelporexecutarasatividadesdocoletordelixodaJVM.Compiladoresquesãoresponsáveisportransformarbytecodeemcódigonativo.Osouvintes,querecebemsinais(informações)etemcomoprincipalobjetivoenviaressasinformaçõesparaoprocessocorretodentrodaJVM.
FalandoumpoucomaissobreessesprocessosparalelosouThread,aJVMpermitequemúltiplosprocessosexecutemconcorrentemente,essarotinaemJavaestádiretamenterelacionadacomumaThreadnativa.TãologoumprocessoparaleloemJavanasça,osseusprimeirospassossão:
AlocaçãodememóriaSincronizaçãodosobjetosCriaçãodosregistradoresespecíficosparaamesmaeaalocaçãodaThreadnativa.
QuandoessarotinageraumaexceçãoapartenativaenviaessainformaçãoparaaJVMqueaencerra.QuandoaThreadterminatodososrecursosespecíficos,tantoparaemJavaquantoapartenativa,sãoentreguesparaJVM.
Comonalinguagem,aJVMoperaemdoistiposdedados:
1. Osprimitivos2. Osvaloresdereferência.
Amáquinaesperaquetodaaverificaçãoquantoaotipotenhasidofeitonomomentodaexecução,sendoqueostiposprimitivosnãoprecisãodetalverificaçãoouinspeçãojáqueelesoperamcomumtipoespecíficodeinstrução(porexemplo:iadd,ladd,fadd,edaddparainteiro,long,floatedoublerespectivamente).
AJVMtemsuporteparaobjetosquesãoouinstânciadeumaclassealocadadinamicamenteouumarray,essesvaloressãodotiporeference,oseufuncionamentoésemelhantedelinguagenscomoC/C++.
OstiposprimitivosexistentesnaJVMsão:
NuméricosBooleanoreturnAdress
Sendoqueostiposnuméricossãoosvaloresinteiroseflutuantes.
Nome Tamanho variação Valorpadrão Tipo
byte 8-bit -2⁷até2⁷ 0 inteiro
short 16-bits -2¹⁵até2¹⁵ 0 inteiro
integer 32-bits -2³²até2³¹ 0 inteiro
long 64-bits -2⁶³até2⁶³ 0 inteiro
char 16-bits UFT-8 '\u0000' inteiro
float 32-bits 0 flutuante
double 64-bits 0 flutuante
ImergindonaJVM
17FuncionamentobásicodaJVM
boolean inteiro false booleano
returnAddress nulo ponteiro
Osformatosdepontoflutuantesãoofloat,comprecisãosimples,eodouble,comduplaprecisão.TantososvalorescomoasoperaçõesseguemoespecificadonopadrãoIEEEparaaritméticadepontoflutuantebinário(ANSI/IEEE.754-1985,NovaYork).Essepadrãonãoincluiapenasvalorespositivosenegativos,maszero,positivoenegativoinfinitoenãoumnúmero(abreviadocomoNanéutilizadopararepresentarvaloresinválidoscomodivisãoporzero).Porpadrão,asJVMsuportamesseformato,mastambémpodemsuportarversõesestendidasdedoubleefloat.
OreturnAdresséusadoapenaspelaJVM,nãopossuirepresentaçãonalinguagem,temseufuncionamentosimilaraponteirosediferentesdostiposprimitivosnãopodemsermodificadosemtempodeexecução.
NaJVMotipobooleanopossuiumsuportebemlimitado,nãoexisteminstruçõesparabooleano,naverdade,elessãocompiladosparausarostiposdeinstruçõesdointeoarraydebooleanosãomanipuladoscomoarraydebyte.Osvaloressãorepresentadoscom1paraverdadeiroe0parafalso.
Falandoumpoucosobreotipodereferência,existemtrêstipos:
1. classes2. array3. interfaces
OValordereferênciaéiniciadocomonull,onulonãoéumtipodefinido,maspodeserfeitocastparaqualquertipodereferência.
Recapitulando,existembasicamentedoistiposdedados:
PrimitivoseReferência.Asreferênciaspossuemosseussubtipos:classe,interfaceearray.OsprimitivospossuemreturnAdress,booleano,flutuantes(floatedoublededuplaesimplesprecisãorespectivamente),inteiros(short,byte,int,long,char).
ImergindonaJVM
18FuncionamentobásicodaJVM
FaladoumpoucosobreostiposdedadosquesãoarmazenadosnaJVMeoseutamanho.Énecessáriotambémquesetenhaciênciadeondesãoarmazenadastaisinformações.AJVMusaregistradoresparaarmazenarváriascoisassendoqueparatodotipodedadoexisteumlocalespecífico.DuranteaexecuçãodeumprogramaexistemregistradosquesãocompartilhadosentretodaaJVMeoutrosquetemavisibilidadedaThreadcorrente.
RegistradoresdaJVM
ImergindonaJVM
19RegistradoresdaJVM
OregistradorPC,Programcounter,écriadotãologoumaThreadécriada,ouseja,cadaThreadpossuioseu.Elepodearmazenardoistiposdedados:
1. Ponteirosnativos2. returnAdress
EssesdadospossueminformaçõesquantoainstruçãoqueestásendoexecutadapelaThread.SeométodoexecutadofornativooPCseráumponteiroenãotemoseuvalordefinido,docontrário,eleteráoendereçodeinstrução,oreturnAdress.
ProgramCounter
ImergindonaJVM
20StackFrame)
AssimcomooPC,eleéumregistradorprivadoparacadaThread,esseregistradorarmazenaframes(queserávistoafrente).SeufuncionamentoésimilaralinguagensclássicascomooC,eleserveparaarmazenarvariáveislocaiseresultadosparciais,invocaçõeseresultadosdosmétodos.Elenãomodificaasvariáveisdiretamentesomenteinserindoeremovendoframesdoregistrador.TãologoacorrenteThreadchamaummétodoumnovoframeéinserindocontadoinformaçõescomoparâmetros,variáveislocais,etc.Assimquandoométodoterminadeumamaneiranormal,quandoacabaométodo,ouporinterrupção,quandoocorreumaexceçãodentrodométodo,esseframeédescartado.OJavaStackpodetertamanhofixooudeterminadodinamicamente.
JavaStack(Javavirtualmachinestack)
ImergindonaJVM
21JavaStack(Javavirtualmachinestack)
Cadaframecontémumvetorparaarmazenarvariáveislocaiseosparâmetroseessetamanhoédefinidoemtempodeexecução.Nessevetorasvariáveisdoubleelongocupamdoiselementosdovetoresãoarmazenadosconsequentemente.VariáveisdotipointereturnAdressocupamumelementodessevetor(byte,shortecharsãoconvertidosparaint).Casoométodosejadainstância,nãosejaestático,oprimeiroelementodessevetorseráocupadopelainstânciaqueestáexecutandoessemétodoeemseguidaosparâmetros,naordemqueforampassados.Casoométodosejadaclasse,ométodosejaestático,Nãohaveráreferênciadainstânciaquechamaométodo,assimoprimeiroelementoseráosparâmetros.
Stackvariables
ImergindonaJVM
22JavaStack(Javavirtualmachinestack)
Comoonomeindica,esseregistradorserveparaarmazenarasinstruçõesqueocorremdentrodométodo,comooregistradordevariáveislocaisosvaloressãoarmazenadosemumvetormasseusvaloresrecuperadospelaremoçãodoúltimoelementodovetoremvezdeserpeloíndice.EleébaseadonaestruturadedadosdePilha(Primeiroaentrarúltimoasair).Otamanhodasvariáveisacontecemdemaneirasemelhanteasvariáveislocais.
Pilhadeoperação,semelhanteaoseu“irmão”,suaunidadepossuiotamanhode32bits,seupasso-a-passosegueomesmodeumapilhaconvencional,oultimoqueentrarseráoprimeiroasair.Nesseexemploseráutilizadoasomadedoisinteiros(10e20).
Comoapilhadeoperaçãoécompostaporunidadede32bits,quandofordoubleoulongeleocuparáasduasunidadesseguidas,nesseexemplosãosomadosdoisdoubles(10.10e20.20)
StackOperand
ImergindonaJVM
23JavaStack(Javavirtualmachinestack)
Essepequenoregistradorpossuiolinkdaconstantpooldaclassequeopossuiocorrentemétodoqueestásendoexecutado.
FrameData
ImergindonaJVM
24JavaStack(Javavirtualmachinestack)
Possuifinalidadedearmazenarvariáveisevaloresnativos(métodosescritosemoutraslinguagens),écriadotãologoumaThreadéiniciadaetodasasThreadspossuemoseuregistrador.
NativeMethodStacks
ImergindonaJVM
25NativeMethodStacks
Esseregistradortemafinalidadedearmazenarlogicamenteostreamdaclasse,essaáreaécompartilhadaentretodasasThreads.LogicamentefazpartedoHeapespace.PorserpartedoHeapelepossuiorecolhimentodememóriaautomático,GarbageCollector.Asclassescontémasseguintesinformações:
Oqualifieddaclasse(Oqualifedéoendereçodasuaclassequeédefinidopelopacotemais.eonomedaClasse,porexemplo,java.lang.Objectoujava.util.Date).Oqualifieddaclassepai(menosparaasInterfaceseojava.lang.Object).Informaçãoseéumaclasseouinterface.Osmodificadores.Alistacomosqualifiedsdasinterfaces.
ParacadaclassecarregadanoJavaécarregadaumconstantpool,quecontémasseguintesinformações:
Oconstantpooldotipo(ParacadaclasseCarregadaécriadaumpooldeconstant,elecontémolinksimbólicoparaosmétodoseparaosatributosalémdasconstantesexistentesnotipo).informaçõesdosatributos(onomedoatributo,otipoeoseumodificador).informaçãodosmétodos(onomedométodo,oseuretorno,onúmeroetipodosparâmetrosemordemeotipoeoseumodificador).ReferênciaparaoClassLoader(classeresponsávelparacarregaraclasse)Variáveisdaclasse(variáveiscompartilhadasentretodasasclassesissoincluiasconstantes).Referênciadaclasse(umainstânciadajava.lang.Classparatodaclassecarregada).
MethodArea
ImergindonaJVM
26MethodArea
Vendoosconceitosnaprática
ImergindonaJVM
27Vendoosconceitosnaprática
Tãologoumainstânciaécriada,asinformaçõesdoseuobjetoficamarmazenadosaqui,esseespaçodememóriatambémécompartilhadoentreasThreads.Oheaptemseumecanismodereclamarmemóriaemtempodeexecuçãoalémdemoverobjetosevitandoafragmentaçãodoespaço.
RepresentaçãodeumavariáveldotipodereferênciadentrodoHeapédiferentedostiposprimitivos,eletemoseumecanismomuitosemelhanteaosponteirosdoC/C++jáqueelenãopossuiainformação,apenasapontaparaolocalqueopossui.Oobjetodereferênciaéconstituídodedoisponteirosmenores:
Umapontaráparaopooldeobjetos,localaondeestãoasinformações.Osegundoapontaráparaoseuconstantpool(quepossuiasinformaçõesdaclassequantoaosatributos,métodos,encapsulamentos,etc.)queficalocalizadonomethodArea.
Arepresentaçãodosvetoressecomportadeformasemelhanteasvariáveisdereferência,maselesganhamdoiscamposamais:
1. Otamanho,quedefineotamanhodovetor2. Umalistadereferênciaqueapontamparaosobjetosqueestãodentrodessevetor.
HeapSpace
ImergindonaJVM
28HeapSpace
ImergindonaJVM
29HeapSpace
EsseregistradoréusadoparacompilaçãoearmazenamentodosmétodosqueforamcompiladosparaomodonativopeloJIT,esseregistradorécompartilhadoportodasasThreads.
Cachedecódigo
ImergindonaJVM
30Cachedecódigo
ObytecodeJavainterpretadonãosãotãorápidoquantooscódigosnativos,paracobriresseproblemadeperformance,aJVMverificamétodoscríticos(regiõesqueexecutamconstantemente,porexemplo)ecompilaparaocódigonativo.Essecódigonativoseráarmazenadodentrodocachedecódigoemumaregiãoforadaheap.AJVMtentaescolherasregiõesmaiscríticasparaquemesmocomogastomemóriaepodercomputacionaldecompilarocódigoparanativo,sejaumadecisãovantajosa.
JustInTime(JIT)Compilation
ImergindonaJVM
31JustInTime(JIT)Compilation
ComissofoifaladosobreosregistradoresquecontémnaJVM,valelembrarquealgumassãoexclusivasporThreadsououtranão.Apilhanativasãoimportantesparaobterrecursosdamáquina,noentanto,osseusvaloressãoindefinidos,jáaspilhasJavasãocriadostãologoummétodoéiniciadoeleésubdivididoemframes,ambasaspilhassãoparticularporThread.OregistradorPCnãopossuiinformações,apenasapontaparaainstruçãoqueestásendoexecutadaepossuiumaporThread.OHeapeomethodAreasãocompartilhadasentreaJVM,todasasThreads,etemaresponsabilidadedearmazenarainstânciadosobjetoseostreamseinformaçõesdaclasserespectivamente.
Recapitulando
ImergindonaJVM
32Recapitulando
UmaveztendonoçãodosregistradoreseaondeficamarmazenadoscadavalornaJVM,seráfaladoumpoucosobreofuncionamentodasinstruções,elapossuiopcodeenotamanhode1byte,daíobytecode.Cadabytecoderepresentaumaaçãoouumaoperação.Amaioriadasoperaçõesdessecódigooperamparaumtipoespecíficodevalor,porexemplo,iload(carregarumintparaapilha)eofload(carregaumfloatparaapilha)possuemoperaçõessemelhantes,noentanto,bytecodesdiferentes.Umaboadicaparasaberotipooperadoésaberaletrainicialdaoperação:iparaumaoperaçãodeinteiro,lparalong,sparashort,bparabyte,cparachar,fparafloat,dparadoubleeaparareferência.
ByteCodes
ImergindonaJVM
33ByteCodes
Essasinstruçõesrealizamtrocadeinformaçõesentreovetordevariáveislocaiseapilhaoperações,sendoquecarregar(definidoporiload,lload,fload,dloadeaload)informaçõesdapilhadevariáveisparaoperaçõesearmazenar(definidopor:istore,lstore,fstore,dstore,astore)realizaoprocessoinverso.
Carregaresalvarinformações
ImergindonaJVM
34Carregaresalvarinformações
Elassãorealizadascomosdoisprimeirosvaloresnapilhadeoperaçõeseretornandooresultado.Oseuprocessamentoésubdivididoemflutuanteseinteirosquepossuemcomportamentosdiferentesparaalgunsresultados,porexemplo,emestourodepilhaedivisãoporzero.
adicionar:iadd,ladd,fadd,dadd.subtrair:isub,lsub,fsub,dsub.multiplicar:imul,lmul,fmul,dmul.divisão:idiv,ldiv,fdiv,ddiv.resto:irem,lrem,frem,drem.negação:ineg,lneg,fneg,dneg.deslocar:ishl,sidh,iushr,lshl,lshr,lushr.bitabit"or":ior,lor.bitabit"and":iand,aterra.bitabitouexclusivo:ixor,lxor.Variávellocalincremente:iinc.Comparação:dcmpg,dcmpl,fcmpg,fcmpl,lcmp.
Operaçõesaritméticas:
ImergindonaJVM
35Operaçõesaritméticas
Asinstruçõesdeconversãodevaloresserveparamodificarotipodavariável,essavariávelpodeterseutipoampliadocomo:
Promoção:intparalong,intparafloat,intparadouble.longparafloatefloatparadouble(i2l,i2f,i2d,l2f,l2d,ef2d)esseampliamentoperdenãoperdeaprecisãodovalororiginal.Oencurtamentodotipocomo:intparabyte,intparashort,intparachar,longparaint,longparafloatparaintoulongpara,doubleparaint,doubleparalongoudoubleparafloat(i2b,i2c,i2s,l2i,f2i,f2l,d2i,d2l,ed2f)valelembrarquetaismodificaçõesexisteapossibilidadedeperderprecisãoouestourodovalor.
Conversãodevalores
ImergindonaJVM
36Conversãodevalores
Instruçõesparaacriaçãoemanipulaçãodeinstâncias(new)Intruçõesparacriaçãodearrays(newarray,anewarray,multianewarray).Acessaratributosestáticosoudainstânciadeumaclasse(getfield,putfield,getstatic,putstatic).Carregar(baload,caload,saload,iaload,laload,faload,daload,aaload)Salvarnapilha(bastore,castore,sastore,iastore,lastore,fastore,dastoreeaastore)Vetoresalémdoseutamanho(arraylength).Checaapropriedadedainstânciaouarray(instanceofecheckcast).
Criaçãoemanipulaçãodeobjetos:
ImergindonaJVM
37Criaçãoemanipulaçãodeobjetos
Instruçõesqueretornamvaloresboolianos(ifeq,ifne,iflt,ifle,ifgt,ifge,ifnull,ifnonnull,if_icmpeq,if_icmpne,if_icmplt,if_icmple,if_icmpgtif_icmpge,if_acmpeq,if_acmpne,tableswitchelookupswitch,goto,goto_w,jsr,jsr_weret`).
Instruçõescondicionais
ImergindonaJVM
38Instruçõescondicionais
Aschamadasdeummétodosão:
invokevirtual:Chamaummétododeumainstânciainvokeinterface:Chamaummétododeumainterfaceinvokespecial:Chamadadeummétodoprivadooudasuperclasseinvokestatic:Realizaachamadadeummétodoestáticoinvokedynamic:Métodoqueconstróiumobjeto
Oretornodeumainstruçãopodeserdefinido(ireturn,lreturn,freturn,dreturneareturn).Duranteaexecuçãodométodocasosejainterrompidademaneirainesperadacomumaexceçãoachamadaathrowérealizada.Osmétodossíncronossãopossíveisgraçasàpresençadeumsimplesencapsulandochamadodemonitor,essestiposdemétodossãodefinidospelaflagACC_SYNCHRONIZEDemseuconstatepool,quequandopossuitalflagométodoentranomonitor(monitorenter)eéexecutado,enenhumaoutraThreadpodeacessá-lo,esai(monitorexit)quandoseumétodoéencerrado(deummodonormalouporinterrupção).
Chamadademétodoseretornodevalores
ImergindonaJVM
39Chamadademétodoseretornodevalores
Umavezfalandodosbytecodeséinteressantes“puxarogancho”efalarcomoficaumaclasseapóssuacompilação.Comojáfoiditoapósacompilaçãoégeradoumbytecode,cujoarquivopossuiaextensão.class,ecadaarquivorepresentaapenasumaclasse.Cadaarquivopossuiasseguintescaracterísticas:
Umnúmeromágicoemhexadecimaldefinindoqueessaclaseéum.classovaloré0xCAFEBABE
Omaioremenornúmerodaversãodoarquivoclassquejuntosdefinemaversãodoarquivo,ouseja,JVMantesrodarprecisaverificarseaversãoVqueelapodeexecutarestarentre:MenorVersão<V<MaiorVersão.
access_flags:Essaflagindicaotipodeencapsulamentodaclasse,métodosedesuaspropriedadesosflagspodemser:
ACC_PUBLIC:flagmétodo,atributospúblicosACC_PRIVATE:flagparaprivadosACC_PROTECTED:protectedACC_STATIC:estáticoACC_FINAL:finalACC_SYNCHRONIZED:indicaummétodosincronizadoACC_BRIDGE:indicaqueométodofoigeradopelocompiladorACC_VARARGS:indicaqueévaragsACC_NATIVE:nativoACC_ABSTRACT:abstratoACC_STRICT:indicaqueométodoéstrictACC_SYNTHETIC:indicaqueométodonãoé“original”
.
this_class:ovalordacorrenteclassedeveterumíndiceválidonaconstantpool
super_class:asinformaçõesdasuperclassedevemestardentroepodeocuparoíndicezeroounão,seocuparoíndicezeroessaclasseéojava.lang.Object,aúnicaclassequenãopossuipai,docontrárioteráqueserumíndiceválidoeterinformaçõesqueapontamparaaclassepai.Asinformaçõesdaclasseédefinidapeloseunomecomoseucaminho,porexemplo,anomedaStringseriajava/lang/String.
constantpool:Oconstantpooléumaestruturadetabelaquecontémonomedasclasses,interfaces,métodos,atributoseoutrasinformaçõesdasclasses.Paraguardaressasinformaçõesexistemdoisregistadoresparcadainformaçãoimportante:Ovetorcomasinformaçõesdaclasse,método,ouatributoseoseucontadorouíndicequefuncionacomolimitadordovetor.Esseéocasodasinterfacesqueaclasseimplementa,atributos,métodosquepossuemseusrespectivosvetoreíndices.
Asdescriçõesdosatributosoudosparâmetrosemummétodoquantoaoseutipoédefinidoaseguir:
BbytesignedbyteCcharDdoubleFfloatIintJlongLClassname;referênciaSshortZboolean[referênciadeumvetor
Classesapóscompilação
ImergindonaJVM
40Classesapóscompilação
[[referênciadeumamatriz
Assim,porexemplo:doubledobro(doubled)éigual(D)DeDoubledobro(Doubled)é(Ljava/lang/Double;)Ljava/lang/Double.
Dentrodaconstantpoolcadainformaçãopossuioseuprimeirobytequeindicaoseutipodeinformação:
CONSTANT_Class7CONSTANT_Fieldref9CONSTANT_Methodref10CONSTANT_InterfaceMethodref11CONSTANT_String8CONSTANT_Integer3CONSTANT_Float4CONSTANT_Long5CONSTANT_Double6CONSTANT_NameAndType12CONSTANT_Utf81CONSTANT_MethodHandle15CONSTANT_MethodType16CONSTANT_InvokeDynamic18
StackMapTable:écompostodestackmapframeetemoobjetivodeverificaçõesparaobytecode
ParaauxiliaradepuraçãonalinguagemJavaexistemalgumasinformaçõesparadepurarocódigoessasvariáveissão:LocalVariableTableeLocalVariableTypeTablequedefineasinformaçõesdasvariáveislocaisparaodebugeLineNumberTabledefineapartedobytecodeesuacorrespondentelinhadecódigo.Paraasanotaçõesexitem:RuntimeVisibleAnnotations,RuntimeInvisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeInvisibleParameterAnnotationsquecontéminformaçõesdasanotaçõesquantoasuavisibilidadeemtempodeexecuçãoaosatributosemétodosounão,existemessasmesmasinformaçõesparaosparâmetrosquantoassuasvisibilidades.AnnotationDefaultdefineasinformaçõesdentrodasanotações.
Ocontadordaconsantpoolpossui16bits,ouseja,elesópodeconter2¹⁶=65535elementos,essemesmonúmerovaleparaonúmerodemétodos,atributos,interfacesimplementadas,variáveislocais,pilhadeoperações(sendoqueparaessesdoisúltimosolongoeodoubleocupamdoisespaços),onomedométodoouatributo.Onúmerodedimensõesdeumamatrizé255omesmonúmerovaleparaaquantidadedeparâmetros,casonãosejaummétodoestáticodeve-seincluirainstância.
Comoobjetivodepôrempráticaevisualizaressesbytescodes,serádemonstradoumsimplescódigoeoseurespectivobytecode.
publicclassPrimeiroTeste{
publicDoublesomarInstancias(Doublea,Doubleb){
Doubleresultado=a+b;
returnresultado;
}
publicdoublesomarDouble(doublea,doubleb){
returna+b;
}
publicintsomarInteiros(inta,intb){
returna+b;
}
publicshortsomarShort(shorta,byteb){
return(short)(a+b);
}
ImergindonaJVM
41Classesapóscompilação
publicstaticintsomarStatic(inta,intb){
returna+b;
}
}
CriadooarquivoPrimeiroTeste.javaeinseridoocódigo1nessearquivo,ospróximospassosserãoentrarpeloterminalnocaminhoqueseencontraoarquivoPrimeiroTeste.java,compilareanalisaroseurespectivobytecodecomosseguintescomandos.
javacPrimeiroTeste.java
javap-verbosePrimeiroTeste
Oresultado:
minorversion:0
majorversion:51
flags:ACC_PUBLIC,ACC_SUPER
Constantpool:
#1=Methodref#5.#21//java/lang/Object."":()V
#2=Methodref#22.#23//java/lang/Double.doubleValue:()D
#3=Methodref#22.#24//java/lang/Double.valueOf:(D)Ljava/lang/Double;
#4=Class#25//PrimeiroTeste
#5=Class#26//java/lang/Object
#6=Utf8
#7=Utf8()V
#8=Utf8Code
#9=Utf8LineNumberTable
#10=Utf8somarInstancias
#11=Utf8(Ljava/lang/Double;Ljava/lang/Double;)Ljava/lang/Double;
#12=Utf8somarDouble
#13=Utf8(DD)D
#14=Utf8somarInteiros
#15=Utf8(II)I
#16=Utf8somarShort
#17=Utf8(SB)S
#18=Utf8somarStatic
#19=Utf8SourceFile
#20=Utf8PrimeiroTeste.java
#21=NameAndType#6:#7//"":()V
#22=Class#27//java/lang/Double
#23=NameAndType#28:#29//doubleValue:()D
#24=NameAndType#30:#31//valueOf:(D)Ljava/lang/Double;
#25=Utf8PrimeiroTeste
#26=Utf8java/lang/Object
#27=Utf8java/lang/Double
#28=Utf8doubleValue
#29=Utf8()D
#30=Utf8valueOf
#31=Utf8(D)Ljava/lang/Double;
Nesseprimeiroresultadopodemosvisualizaraconstantpooleamenoreamaiorversãodoclass.OConstantPoolcontémasinformaçõesdarespectivaclasse,jáquetodaclassepossuiessainformação,inclusiveasInnerClasses,eelessãoarmazenadasemumvetor.
publicPrimeiroTeste();
flags:ACC_PUBLIC
Code:
stack=1,locals=1,args_size=1
0:aload_0
1:invokespecial#1//Methodjava/lang/Object."":()V
4:return
LineNumberTable:
line1:0
ImergindonaJVM
42Classesapóscompilação
LocalVariableTable:
StartLengthSlotNameSignature
050thisLPrimeiroTeste;
publicjava.lang.DoublesomarInstancias(java.lang.Double,java.lang.Double);
flags:ACC_PUBLIC
Code:
stack=4,locals=4,args_size=3
0:aload_1
1:invokevirtual#2//Methodjava/lang/Double.doubleValue:()D
4:aload_2
5:invokevirtual#2//Methodjava/lang/Double.doubleValue:()D
8:dadd
9:invokestatic#3//Methodjava/lang/Double.valueOf:(D)Ljava/lang/Double;
12:astore_3
13:aload_3
14:areturn
LineNumberTable:
line5:0
line6:13
LocalVariableTable:
StartLengthSlotNameSignature
0150thisLPrimeiroTeste;
0151aLjava/lang/Double;
0152bLjava/lang/Double;
1323resultadoLjava/lang/Double;
publicdoublesomarDouble(double,double);
flags:ACC_PUBLIC
Code:
stack=4,locals=5,args_size=3
0:dload_1
1:dload_3
2:dadd
3:dreturn
LineNumberTable:
line10:0
LocalVariableTable:
StartLengthSlotNameSignature
040thisLPrimeiroTeste;
041aD
043bD
publicintsomarInteiros(int,int);
flags:ACC_PUBLIC
Code:
stack=2,locals=3,args_size=3
0:iload_1
1:iload_2
2:iadd
3:ireturn
LineNumberTable:
line13:0
LocalVariableTable:
StartLengthSlotNameSignature
040thisLPrimeiroTeste;
041aI
042bI
publicshortsomarShort(short,byte);
flags:ACC_PUBLIC
Code:
stack=2,locals=3,args_size=3
0:iload_1
1:iload_2
2:iadd
3:i2s
4:ireturn
LineNumberTable:
line17:0
LocalVariableTable:
StartLengthSlotNameSignature
050thisLPrimeiroTeste;
051aS
052bB
publicstaticintsomarStatic(int,int);
flags:ACC_PUBLIC,ACC_STATIC
ImergindonaJVM
43Classesapóscompilação
Code:
stack=2,locals=2,args_size=2
0:iload_0
1:iload_1
2:iadd
3:ireturn
LineNumberTable:
line21:0
LocalVariableTable:
StartLengthSlotNameSignature
040aI
041bI
Aovermososmétodospodemosperceberquetodososmétodospossuiotamanhodapilhadeoperaçãoedevariáveisalémdotamanhodasvariáveisenvolvidasemumdeterminadométodo.
Noprimeiroqueéométodoconstrutor,essemétodoéconstruídoautomaticamentecasonãosejafeitapelousuário,elepossui1tamanhodeoperação,jáquesetratadacriaçãodeumobjetodotiporeferênciaeesseocupaumespaçonovetordeoperação,1notamanhodevariável,jáqueeleéummétodonãoestáticoeessasinformaçõespertenceainterfacequeaestáchamandoeonúmerodevariáveisutilizadasédeumjáqueestamosnosreferindoainstânciacriada.Nosegundométodo,asomadeinstânciaseretornaumaterceirainstância,(Ljava/lang/Double;Ljava/lang/Double;)Ljava/lang/Double,elepossuiotamanhodetrêsnapilhadevariáveis,jáqueumaparaasduasvariáveisdereferênciaeumajáqueométodoédainstância,quatronotamanhodepilhadeoperações,jáquenoprocessoosDoublesserãotransformadosemdoubleprimitivo,assimcadaumocuparáduasunidadesnovetor.OcampoLineNumberTableéparaajudaradebugarocódigonumdeterminadométodo,LineNumberTable5:0,dizquealinhadenúmerocincodocódigojavaequivaleainstruçãodocomeço,linhazerodobytecodeeline6:13,alinhaseisdocódigojavacomeçanainstruçãodobytecodenúmero13.OcampoLocalVariableTabletambémserveparadebugaredefineonomedocampo,tipo,linhaqueelenasceeaquemorre.IssodemonstracomoédiferenteocódigoJavaeobyteCodegerado.
Nessecapítulofalamosumpoucosobreobytecodeeoseumaceteparaentender,olhandopelasiniciasdocomando,valelembrarqueduranteaexecuçãoosboolianos,byte,shortssãotransformadosparainteiros,assimsuasoperaçõessãorealizadascomointeiros.SedemonstrouquãodiferenteéocódigoJavadobytecodegeradoeemfunçãodissosecrioutabelasevariáveis,porexemplo,LocalVariableeLineNumberTableparaauxiliarnahoradedebugar,essasvariáveissãoutilizadaspelomododebugdasIDEsmodernas.
ImergindonaJVM
44Classesapóscompilação
TodaclassepelaJVMpossuioseuciclodevida,ecomeçaquandoelanascedentrodaJVM,esseprocessoéfeitodemodolazy,ouseja,aclassXserácarregadanomomentoemquefornecessário,aoinstanciarumobjetoéfeitooprocessodeencontrararepresentaçãobináriadaclasse,carregarasinformaçõesecolocarasuaclassedentrodaJVM,entãocriaroobjeto.TodasasclassesprecisampassarporesseprocessoinclusiveaclassequeiniciaaJVM.Casoaclasseestendadeumaclasseouimplementeinterfacesasmesmasterãodesercarregadasprimeiro.Comocadaumdessestrêsprocessospossuidetalhes,sediscriminaráasaçõesdecadaum.
Ciclodevidadeumaclasse
ImergindonaJVM
45Ciclodevidadeumaclasse
OcarregamentodeclasseconsisteemsubiraclasseparamemóriaprincipalecolocarnaJVM,esseprocessoaconteceumavezcompotqualifield,comessestreamcarregadoserealizaoparserparaoregistradormethodAreaeconcluindogeraainterfacequerepresentatalarquivo,ojava.lang.Class.
AinterfaceClasséoprodutodoprocessodecarregaraclasseparaamemóriaprincipal,éarepresentaçãodoarquivo,comissoelecontémasinformaçõesdomesmo,comolistadosmétodos,atributos,interfaces,anotações,etc.
AsClassesporsuavez,sãocarregadaspeloClassLoader(comexceçãodosarrayquenãopossuirepresentaçãobinária).
ImergindonaJVM
46Ciclodevidadeumaclasse
NaJVMexistemmúltiplosclasseloaderscomdiferentesregras,assimpodemosclassificar-lascomo:
BootStrapeleseencontranotopodahierarquiadosclassloaders,esseobjetoéresponsávelporcarregaraAPIbásicadoJava,eosobjetosquepossuamumaltíssimoníveldeconfiançapelaJVM.ExtensãoéresponsávelporcarregarasAPIpadrõesdoJavacomoasdesegurançaeCollection.Osystemesseéoclassloaderpadrãodaaplicação,eleéresponsávelporcarregarasclassesqueestãocontidasnoclasspath.AbaixodoSystemClassLoaderousuárioadicionaráumclassloader,quetemalgunsmotivosespeciais,entreelesdefinirumgrupodeclassloaderespecíficoparaumdomínioouaplicação,éocasodosservidoresdeaplacaçãocomootomcateoGlassfish.
ApósaclassesercarregadaopróximopassoserálinkarparaJVM,esseprocessoconsistenaverificaçãodaclasserecém-carregada,eleverificaapalavra-chave,seaestruturaestácorreta,otamanhodosarquivos,apósaverificaçãosãoalocadasmemóriasparaosatributoseserãosetadososvalorespadrãodoscampos,sãocarregadososatributosestáticos,encerrandoesseprocessotodososlinkdereferênciasãosubstituídosporlinksdiretos.
Noúltimoestágioseráacriadaainstânciacomachamadadométodoconstrutor,sendoqueanteséchamadooconstrutordasuperclasse,nãoexisteverificaçãoparaasinterfacesapenasseosmétodosforamimplementados.
ImergindonaJVM
47Ciclodevidadeumaclasse
DiferentedealgumaslinguagensoJavapossuiumgerenciamentodememóriaautomática,issopermitequeamemóriadeumobjetonãomaisutilizadosejaretomada,essacertamenteéumadasgrandesvantagemdaplataformaemrelaçãoaoC.OprimeirodesafiodaJVMéidentificarquaisobjetosdispensáveis,eassimretomaramemóriacomissofoirealizadováriastécnicasparaassimofazer.
OmaisconhecidocertamenteéoMarkandSweep,basicamentedoisprocessosquemarcaosobjetosutilizadosenofinalosobjetosnãomarcadossãodispensáveispararetomaramemória,omaiorproblemaéquetodososprocessossãoparadosparaexecutartalprocedimentoinviabilizandochamá-loconstantemente.Emfunçãodesseproblemacitadoanteriormentefalaremosdosegundoalgorismo,quelevaemconsideraçãoquemuitosobjetosnãopossuemumalongavida,noentanto,algunslevambastantetemponamemória,assimosalgoritmossebaseiaemgeraçõesquedivideamemóriaemtrêspartes(jovem,efetivaepermanente).
Paramelhorgerenciarocoletordelixoamemóriaheapédividiabasicamenteemalgumaspartes:
YoungGeneration:Éondecontémosobjetosrecém-criados,agrandemaioriadosobjetosmorremdentrodessaárea.Elaésubdividaemduaspartes:Eden(localaondeoobjetosnascem)eSurvivers(N)locaisaondeosobjetosvãopassandoatésairdaYoungGeneration.Oseufuncionamentoédemaneirasimples:OsobjetosnascemnoEden,depoisdeumtempo,osobjetossãocopiados“vivos”paraosSurvivers,osobjetosquenãoforamcopiadosnãosãoapagados,masnofuturo,outrosobjetosocuparãoseuespaço.ComopassardascoleçõesosobjetosexistentessaemdaYoungevãoparaTenuredgeneration,nesseespaçoogerenciamentodeobjetosérealizadodeformadiferente,assimnãohácópia,existemalgoritmosderivadosdoSwepandMark,comosobjetosapagadosapróximapreocupaçãoseráemrelaçãoafragmentaçãodoregistrador,assimhaveráoprocessodecompactaçãodosdados.
GarbageCollector
ImergindonaJVM
48GarbageCollector
Comentadoumpoucosobreosprocessosdeminorcollector(procedimentodegenerationquecópiaobjetospararegistradoressobreviventes)eomaiorcollector(procedimentocujoosalgoritmossãoderivadosdeMarkandSwepqueapagaosobjetosnãoutilizadosequandofragmentadaamemóriahaveráoprocedimentodecompactação,valelembrarqueparatalprocedimentoaJVMparatodososseusprocessos).OobjetivoagoraseráfalaroestiloouomododosGarbageCollector.
ImergindonaJVM
49GarbageCollector
Esseestiloémuitoindicadoparapequenasaplicaçõesouhardwaredepequenopodercomputacionaleapenasumprocessador,monocore,elesenabaseianaexecuçãodosprocessos,maioremenorcollector,utilizandoapenasumaThread,dessemodopodeeconomizarrecursos,porémcasohajaumgrandenúmerodememóriahaveráumgrandedelay.
ImplementaçãoSerial
ImergindonaJVM
50ImplementaçãoSerial
Trabalhadeformasemelhantedaserial,noentanto,seráutilizadoduasoumaisThreadsporcoleção,assimoprocessotendeaserrealizaremumtempomenor,porémutilizandomaisrecursosdemáquina.
ImplementaçãoParalelo
ImergindonaJVM
51ImplementaçãoParalelo
Essetambémexecutaprocessosemparalelos,noentanto,oseuobjetivoédiminuirotempodomaiorcollector,mesmoqueparaissooexecuteváriasvezes.Indicadoparamuitosobjetosdurammuitotempo,assimelesficamnaTurnered.EmresumoseuprocessodividerealizarmarcaçãoemquetodasasThreadestãoparadasemarcaçõesconcorrentes,masaremoçãodosobjetosocorremsemnenhumprocessoparar,oúnicoproblemadesseestiloéofatoquenãohácompactaçãodedadosperiódicos,apenasquandosetornacrítico(usandooSerialOdl).
ImplementaçãoConcurrent
ImergindonaJVM
52ImplementaçãoConcurrent
Tambéméconcorrente,masérealizadodeformaincremental(realizadoaospoucoseagendadoentreasminor-collector)seufuncionamentoébemsemelhanteaoanterior,masadicionaumprocessoqueéredimensionareprepararosdadosparaumapróximacoleçãoocicloquecontrolaotempoqueocolectorficanoprocessador.Casotenhaproblemascomfragmentação,eletambémacionaráoserialOdl(quealémderemoverosdadostambémcompactaráosobjetossobreviventes).
ImplementaçãoIncrementalConcurrent
ImergindonaJVM
53ImplementaçãoIncrementalConcurrent
Lançadonaversão7doJava,oGarbagefirst,écoletorparaleloprojetadaparaterumgrandethroughput,elefoiprojetadoparasistemascomumaaltaquantidadedememóriaedeprocessadores.ParaalcançarseuobjetivoeledivideigualmenteotamanhodoHeap.Assimcomoosdoisúltimosconcorrentes,elepossuiumafaseemquerealizaamarcaçãoconcorrente,erealizaocalculodeobjetosalcançáveisdecadaregião,assimdetemposemtempos,todososprocessossãoparadososobjetosvivossãocopiadosparaoutraregião,fazendocomquearegiãoemquestãosejatotalmentetomada.Terãomaiorprioridadeasregiõescomomaiornúmerodeobjetos“mortos”(assimseterámenostrabalhoemrealizaracopiaparaaoutraárea).OG1veioparasubstituirostiposconcorrentedecoleção(CMSeI-CMS)devidoalacunaqueambosdeixavam.
Nãoterumtempodeterminadoparadeixaroprocessadoreacompactaçãodoheap(umavezquemuitocríticachamadaoserialOdl).OG1tomacomoestratégiaofatodesermaisfácilcontrolarpequenasregiõesdoqueumageração,umoutroaspectoéquetãologoasmemóriasexistentestenhasidocopiadoparaumanovaárea,aanterioréconsideradaumaárealimpa.
ImplementaçãoGarbageFirst
ImergindonaJVM
54ImplementaçãoGarbageFirst
MuitosefaladoJava,principalmentedofatodelesermultiplataforma,talvezessacaracterísticaemespecial,desecompilarumavezepoderrodaremdiversasplataformas,tornouoJavaalinguagemeplataformamaispopularnomundo.MuitosetemexploradojáquetodaacomplexidadeéfeitapelaJVM,massurgeaseguintedúvida:ComoaJVMfazisso?Comoelaconseguirabstrairasoutrasplataformasparamin?ObteresseconhecimentoémuitoimportanteumavezquepodesernecessárioutilizarumrecursoespecíficodamáquinaefazercomesserecursoconversediretamentecomaJVM.
AcomunicaçãoentreaJVMeocódigonativoquaseemsuagrandemaioriaéfeitonalinguagemC/C++umavezqueelaspossuemopadrãoANSIequeomesmoécompatívelcomagrandemaioriadasplataformas,assimépossívelumgrandeaproveitamentodecódigo,masemalgunscasosénecessárioquesejafeitaumaimplementaçãoespecíficaparacadaplataformaouqueexistecompatibilidadecomumsistemalegadoquefoifeitoemC,porexemplo.AportaentreocódigonativoeoJavaéconhecidocomoJNI(JavaNativeInterface).EsserecursoémuitointeressantetambémparafazeraponteparaplataformasemqueoJavaaindanãoatingiu.DentrodaJVMesserecursoéusadoparaalgunsnaplataformaJSE,porexemplo,JavaI/O,algunsmétodosdaclassejava.lang.System,JavaSound,acomunicaçãoentreaclasse,oarquivo.class,easuarepresentaçãodentrodaJVM,aimplementaçãodainterfacejava.lang.Class,asimplementaçõesdoGarbageColectordentreoutrosrecursos.ComoJNIépossívelchamarmétododoobjeto,instanciarclasses,verificarestadodoobjetocriadodentrodaJVM,dentreoutrosrecursos.
Noentanto,usarorequeralgumasresponsabilidades,valelembrarqueusaroJNIperdeaportabilidade,umerronativonãoécontroladopelaJVM(Valelembrarnaparteemquesefalouderegistrados,apilhanativaeoPCquandoapontaparaumprocessonativo,nãosesabeoseuvalorpreciso),nãoépossíveldebugarocódigonativoatravésdaplataformaJava,casoaconteceumerronativopodequebraraexecuçãodaJVM,elenãoproverumGarbageCollectorautomáticoouqualquergerenciamentoporpartedaJVM.AssimémuitoimportantesaberomomentoemqueseusaráoJNI.
OsobjetosemJavapodemsermapeadosparaobjetosnativosevirse-versa,paragarantiracomunicaçãodeduasmãos,assimépossívelestarpassandoumobjetoJavaparaoladonativoveroseuvalor.
TipoemJava TipoNativo
boolean jboolean
byte jbyte
char jchar
double jdouble
float jfloat
int jint
long jlong
short jshort
void void
ComoobjetivodedarumpequenoexemplocomoJNIserámostradodoissimplesexemplos,oprimeiroseráo“olámundo”comoJNIeosegundoseráummétodoestáticoquecalculaodobrodoresultadopassado,paraissoénecessárioquesetenhainstaladooGCCeoJDK.Ocódigoserábemsimples,noprimeirocasoseráenviadoonomeporparâmetroeessaStringserápassadaparaovalornativo,umaveznonativoseráconcatenadoo“Helloworld”comonomedigitado,nosegundoexemplo,osegundoparâmetroseriacalculadooseudobro.
PrimeiramenteserácriadoaclasseHelloWorld.java.
InterfaceNativaJava
ImergindonaJVM
55InterfaceNativaJava
publicclassHelloWorld{
privatenativevoidchamarMensagem(Stringnome);
publicnativestaticintdobrar(intvalor);
publicstaticvoidmain(String[]args){
Stringnome=args[0]==null?"nome":args[0];
intvalor=args[1]==null?2:Integer.valueOf(args[1]);
HelloWorldhelloWorld=newHelloWorld();
helloWorld.chamarMensagem(nome);
intresultado=HelloWorld.dobrar(valor);
System.out.println("Odobrode"+valor+"é:"+resultado);
}
static{System.loadLibrary("HelloWorld");}
}
Emseguidacompilamoscomoseguintecomando:
javacHelloWorld.java
Umavezoarquivocompilado,seránecessáriogerarainterfaceJNIcomoseguintecomando:
javah-jniHelloWorld
ComocomandoserágeradoumarquivoHelloWorld.h.
/*DONOTEDITTHISFILE-itismachinegenerated*/
#include<jni.h>
/*HeaderforclassHelloWorld*/
#ifndef_Included_HelloWorld
#define_Included_HelloWorld
#ifdef__cplusplus
extern"C"{
#endif
/*
*Class:HelloWorld
*Method:chamarMensagem
*Signature:(Ljava/lang/String;)V
*/
JNIEXPORTvoidJNICALLJava_HelloWorld_chamarMensagem
(JNIEnv*,jobject,jstring);
/*
*Class:HelloWorld
*Method:dobro
*Signature:(I)I
*/
JNIEXPORTjintJNICALLJava_HelloWorld_dobrar
(JNIEnv*,jclass,jint);
#ifdef__cplusplus
}
#endif
#endif
Reparequenainterfaceométodopossuioseguinteformato:
Java_NomeClasse_nomeMetodo.Emrelaçãoaosparâmetrosoprimeiroelemento,oJNIEnv,eleéumponteiroqueapontaparaumvetornoqualpossuitodasasfunçõesdoJNI,osegundodependeseémétododaclasseoudainstância.Casosejaestático,ousejaométodopossuaapalavra-chavestatic,opróximoparâmetroseráojclassqueconteráas
ImergindonaJVM
56InterfaceNativaJava
informaçõesdaclasse,casosejadainstânciaopróximoparâmetroseráojobjectqueconteráasinformaçõesdainstância.
Opróximopassoéacriaçãodoarquivoque“implemente”ainterfacedoHelloWorld.h,assimserácriadooHelloWorld.cqueimplementetalinterface.
#include<jni.h>
#include"HelloWorld.h"
#include<stdio.h>
JNIEXPORTvoidJNICALLJava_HelloWorld_chamarMensagem(JNIEnv*env,jobjectobj,jstringnome){
constchar*nomeNativo=(*env)->GetStringUTFChars(env,nome,NULL);
printf("HelloWorld!!!!%s\n",nomeNativo);
return;
}
JNIEXPORTjintJNICALLJava_HelloWorld_dobrar(JNIEnv*env,jclassclasse,jintvalor){
return2*valor;
}
Comoarquivocriadoopróximopassoéacompilação,levandoemconsideraçãoasdevidasimportações,comosetratadelibsnativasaspastasvariamdeacordocomaplataforma.Nocasodolinuxparacompilarseránecessáriooseguintecomando:
gcc-olibHelloWorld.so-shared-I$JAVA_HOME/include-I$JAVA_HOME/linuxHelloWorld.c
Umavezcompiladoocódigo-fonteeotransformadoemumalib,nocasodolinuxoarquivocomextensão.sodeSharedObject.Opróximopassoserá“linkar”oarquivonativocomoprojeto,oprimeiropassoécarregarabibliotecadentrodocódigojava(paraissoseráutilizadoocomandoSystem.loadLibrary("NomedaLib");).
Opróximopassoécolocaralibnativanoclasspathnosistemaoperacionaloudefiniroseucaminhopeloparâmetrojava.library.pathaoexecutaroprojetojava.Nesseexemploseráutilizadoasegundaopçãojuntamenteoparâmetroqueseráonomedaqueseráimpressonoconsole,assimocomandoficará:
java-Djava.library.path=.HelloWorldOtávio4
Asaídaserá:
HelloWorld!!!!Otávio
`Odobrode5é:10
ComissoseapresentouorecursodoJNI,ainterfacequesecomunicaoJVMparalinguagensnativacomoCeC++edasuaimportânciaparaaJVMcomoaimplementaçãodoGarbageCollector,suaexistênciaemalgumasAPIscomooJavaSoundalémdeseintegrarcomcódigolegadoecomplataformascujoaJVMatéomomentonãoatingiu.Noentanto,valesalientarqueseperdeofatormultiplataformaenãoserámaisgerenciadopelaJVMusandoesterecurso.AprendersobreJNIémuitoimportanteparacompreenderocódigodamáquinavirtualJava,masénecessárioumconhecimentonalinguagemCeC++.`
ImergindonaJVM
57InterfaceNativaJava
OOpenJDKéumprojetoquefoiiniciadopelaSunMicrosystems,atualmentemantidopelaporváriasempresaseacomunidade,paraacriaçãodeumJavaDevelopmentKitbaseadototalmenteemsoftwarelivreedecódigoaberto.Oprojetofoiiniciadoem2006etemcomobaseoHotSpot(ajvmdaSun).Umaconquistaparaoprojetoquevalesalientaréqueapartirdaversão7doJavaoOpenJDKéaversãodereferência,masalémdessaousodoOpenJDKtegarantealgumasvantagens:
1. Aprimeiravantageméqueeleéopensource,ouseja,podeestudaroseucódigofonte.
2. Elaagoraéaimplementaçãodereferência,ouseja,sefazerumaplicativoquerodeemqualquerJVM,essagarantiaserápossívelapenascomoOpenJDK
3. AcomunidadeJavaécertamenteumadascomunidadesmaisfortesdomundo.AJVMdoprojeto,porexemplo,estápassandoporconstantesrefatoraçõesparamelhoriadeperformance,atualizaçãodebibliotecaseatualizaçãodocódigosemfalarqueparaadicionarqualquerrecursoénecessárioquesetenhatestes.
4. AOracledoouocódigofontedojRockitenojava8,previstoparaofinalde2013,ocódigosejaintegradocomoHotspot.Ouseja,noopenjdkhaveráosmelhoresdedoismundosemumsólugar.
5. Váriasempresasfazempartedesseprojeto,ouseja,éumaJVMcomoKnow-howdeváriasempresasemtodoomundo.EmpresascomoIBM,Apple,SAP,Mac,Azul,Intel,RedHatetc.fazempartedoprojeto.
6. SeaOracledeixaroJava(Algoqueeuachomuitodifícilpordiversosmotivos)edeixardefazeraJVM.OOpenJDKnãoseráemnenhummomentoabaladojáqueexistemoutrasempresasapoiandoalémdacomunidade.
AdiferençaentreessasduasJVMs,HotSpot(aJVMmaispopulardaSunatualmentedaOracle)eoOpenJDK,estánaadiçãodecódigosfechadosalémdepequenasmudançasnaimplementaçãoparaimplementaçõesfechadasparaaJVMdaOracle,adessemelhançaédecercade4%decódigo.OqueaconteceéquenemtodososcódigosforamabertoscomêxitojáquealgunspertenceaterceirosesãoapenaslicenciadosnaépocapelaSun.
TodamudançadentrodoJavaérealizadaatravésdasubmissãodeumaJSR,JavaSpecificationRequests,queéumdocumentoquepossuiinformaçõesquantoamelhoriaaserfeitaeseusimpactosdentrodalinguagem.EssasJSRssãoselecionadasapartirdoJCP,JavaCommunityProcess,queécompostapor31instituições(PodemosdestacaraparticipaçãodaOracle,SouJavaeLondonComunity).EssasinstituiçõestêmamissãodevotarafavoroucontraumaJSR.Quandoexisteumamudançanaplataforma(JSE,JEE,JME)éditoqueelapossuiumguarda-chuvadeespecificações(JáqueumamudançadeplataformaéresultadodediversasJSRs,porexemplocomoJava7,
OprojetoOpenJDK
ImergindonaJVM
58OprojetoOpenJDK
documentadanaJSR336,possuidentrodelaasJSRs314oprojetoCoin,203oNIO2,292oinvokedynamic).
ComoOpenJDKnãoédiferente,todasassuasmudançasprecisamestardocumentadasemJSRsquesãovotadaspeloJCP,nocasodeumanovaversãodaplataformaJSE,precisaterumconjuntodeJSRouumguarda-chuvadeespecificação.Noentanto,paramelhorias,refatoraçõesexisteoJEP,JDKEnhancementProposalsoupropostasdemelhoriasparaoJDK.
Ocódigodoprojetoémantidoemmercurialemaisinformaçõesdoprojetopodeserencontradoem:http://openjdk.java.net/
Parabaixarocódigoénecessário:
hgclonehttp://hg.openjdk.java.net/jdk8/jdk8jdk8(parabaixarocódigofonteemsuamáquina).
cdjdk8(entrandonodiretório,ondeseencontraocódigofonte).
shget_source.sh(shellscriptparabaixarocódigofontedosmódulosdaJVM).
AobaixarocódigoseveráqueoprojetoOpenJDKécompostoporsubprojetos:
ImergindonaJVM
59OprojetoOpenJDK