Imergindo Na Jvm

Preview:

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