logo

Gestió de memòria en Java

A Java, la gestió de memòria és el procés d'assignació i desassignació d'objectes, anomenat gestió de memòria. Java gestiona la memòria automàticament. Java utilitza un sistema automàtic de gestió de memòria anomenat a abocador . Per tant, no estem obligats a implementar la lògica de gestió de memòria a la nostra aplicació. La gestió de la memòria Java es divideix en dues parts principals:

    Estructura de memòria JVM Treball del Recollidor d'escombraries

Estructura de memòria JVM

JVM crea diverses àrees de dades de temps d'execució en un munt. Aquestes àrees s'utilitzen durant l'execució del programa. Les àrees de memòria es destrueixen quan surt la JVM, mentre que les àrees de dades es destrueixen quan surt el fil.

Gestió de memòria en Java

Àrea del mètode

L'àrea del mètode és una part de la memòria del munt que es comparteix entre tots els fils. Es crea quan s'inicia la JVM. S'utilitza per emmagatzemar l'estructura de classe, el nom de la superclasse, el nom de la interfície i els constructors. La JVM emmagatzema els següents tipus d'informació a l'àrea del mètode:

  • Un nom complet d'un tipus (per exemple: String)
  • Modificadors del tipus
  • Nom directe de la superclasse del tipus
  • Una llista estructurada dels noms totalment qualificats de les superinterfícies.

Zona Heap

Heap emmagatzema els objectes reals. Es crea quan s'inicia la JVM. L'usuari pot controlar el munt si és necessari. Pot ser de mida fixa o dinàmica. Quan utilitzeu una paraula clau nova, la JVM crea una instància per a l'objecte en un munt. Mentre que la referència d'aquest objecte s'emmagatzema a la pila. Només existeix un munt per a cada procés JVM en execució. Quan el munt s'omple, es recullen les escombraries. Per exemple:

 StringBuilder sb= new StringBuilder(); 

La sentència anterior crea un objecte de la classe StringBuilder. L'objecte s'assigna a la pila i la referència sb s'assigna a la pila. El munt es divideix en les parts següents:

  • Generació jove
  • Espai supervivent
  • vella generació
  • Generació permanent
  • Memòria cau de codi

Tipus de referència

Hi ha quatre tipus de referències: Fort , Feble , Suau , i Referència fantasma . La diferència entre els tipus de referències és que els objectes del munt als quals es refereixen són aptes per a la recollida d'escombraries segons els diferents criteris.

Referència forta: És molt senzill ja que l'utilitzem a la nostra programació diària. Qualsevol objecte que tingui una referència forta adjunta no és apte per a la recollida d'escombraries. Podem crear una referència forta utilitzant la següent declaració:

 StringBuilder sb= new StringBuilder(); 

Referència feble: No sobreviu després del següent procés de recollida d'escombraries. Si no estem segurs de quan es tornaran a demanar les dades. En aquesta condició, podem crear-hi una referència feble. En cas que, si el col·lector d'escombraries processa, destrueix l'objecte. Quan tornem a intentar recuperar aquest objecte, obtenim un valor nul. Es defineix a java.lang.ref.WeakReference classe. Podem crear una referència feble utilitzant la següent declaració:

 WeakReference reference = new WeakReference(new StringBuilder()); 

Referència suau: Es recull quan l'aplicació s'està quedant sense memòria. El recol·lector d'escombraries no recull els objectes de fàcil accés. Tots els objectes de referència suaus es recullen abans que llanci un OutOfMemoryError. Podem crear una referència suau utilitzant la següent declaració:

 SoftReference reference = new SoftReference(new StringBuilder()); 

Referència fantasma: Està disponible a java.lang.ref paquet. Es defineix a java.lang.ref.PhantomReference classe. L'objecte que només té una referència fantasma que els apunta es pot recollir sempre que el recol·lector d'escombraries vulgui recollir-lo. Podem crear una referència fantasma utilitzant la instrucció següent:

 PhantomReference reference = new PhantomReference(new StringBuilder()); 

Àrea de pila

L'àrea de pila es genera quan es crea un fil. Pot ser de mida fixa o dinàmica. La memòria de pila s'assigna per fil. S'utilitza per emmagatzemar dades i resultats parcials. Conté referències a objectes d'heap. També conté el valor en si mateix en lloc d'una referència a un objecte del munt. Les variables que s'emmagatzemen a la pila tenen una certa visibilitat, anomenada àmbit.

Marc de pila: El marc de pila és una estructura de dades que conté les dades del fil. Les dades del fil representen l'estat del fil en el mètode actual.

  • S'utilitza per emmagatzemar resultats parcials i dades. També realitza enllaços dinàmics, retorn de valors per mètodes i excepcions d'enviament.
  • Quan un mètode invoca, es crea un marc nou. Destrueix el marc quan es completa la invocació del mètode.
  • Cada fotograma conté la matriu de variables locals (LVA), la pila d'operands (SO) i les dades de trama (FD).
  • Les mides de LVA, OS i FD es determinen en temps de compilació.
  • Només un marc (el marc per al mètode d'execució) està actiu en qualsevol punt d'un determinat fil de control. Aquest marc s'anomena marc actual i el seu mètode es coneix com a mètode actual. La classe de mètode s'anomena classe actual.
  • El marc atura el mètode actual, si el seu mètode invoca un altre mètode o si el mètode es completa.
  • El marc creat per un fil és local a aquest fil i no es pot fer referència a cap altre fil.

Pila de mètodes natius

També es coneix com a pila C. És una pila per a codi natiu escrit en un llenguatge diferent de Java. Java Native Interface (JNI) crida a la pila nativa. El rendiment de la pila nativa depèn del sistema operatiu.

Registres de PC

Cada fil té un registre de comptador de programes (PC) associat. El registre del PC emmagatzema l'adreça de retorn o un punter natiu. També conté l'adreça de les instruccions JVM que s'estan executant actualment.

Treball del Recollidor d'escombraries

Visió general del col·lector d'escombraries

Quan un programa s'executa en Java, utilitza la memòria de diferents maneres. El munt és una part de la memòria on viuen els objectes. És l'única part de la memòria que participa en el procés de recollida d'escombraries. També es coneix com a munt d'escombraries. Tota la recollida d'escombraries s'assegura que el munt tingui el màxim d'espai lliure possible. La funció del col·lector d'escombraries és trobar i eliminar els objectes als quals no es pot accedir.

Assignació d'objectes

Quan un objecte s'assigna, la JVM JRockit comprova la mida de l'objecte. Distingeix entre objectes petits i grans. La mida petita i gran depèn de la versió de JVM, la mida de la pila, l'estratègia de recollida d'escombraries i la plataforma utilitzada. La mida d'un objecte sol estar entre 2 i 128 KB.

Els objectes petits s'emmagatzemen a Thread Local Area (TLA), que és un tros lliure de la pila. TLA no es sincronitza amb altres fils. Quan el TLA s'omple, sol·licita un nou TLA.

D'altra banda, els objectes grans que no encaixen dins del TLA s'assignen directament al munt. Si un fil utilitza l'espai jove, s'emmagatzemarà directament a l'espai antic. L'objecte gran requereix més sincronització entre els fils.

Què fa Java Garbage Collector?

JVM controla el col·lector d'escombraries. JVM decideix quan realitzar la recollida d'escombraries. També podem demanar a la JVM que executi el col·lector d'escombraries. Però no hi ha cap garantia sota cap condició que la JVM compleixi. JVM executa el col·lector d'escombraries si detecta que la memòria s'està esgotant. Quan el programa Java sol·licita el col·lector d'escombraries, la JVM sol concedir la sol·licitud en poc temps. No assegura que les sol·licituds acceptin.

El punt a entendre és que ' quan un objecte esdevé apte per a la recollida d'escombraries? '

Cada programa Java té més d'un fil. Cada fil té la seva pila d'execució. Hi ha un fil per executar al programa Java que és un mètode main(). Ara podem dir que un objecte és apte per a la recollida d'escombraries quan cap fil viu no hi pot accedir. El recol·lector d'escombraries considera que aquest objecte es pot suprimir. Si un programa té una variable de referència que fa referència a un objecte, aquesta variable de referència disponible per al fil viu, aquest objecte es crida accessible .

Aquí sorgeix una pregunta que ' Una aplicació Java pot quedar-se sense memòria? '

La resposta és sí. El sistema de recollida d'escombraries intenta treure objectes de la memòria quan no estan en ús. Tanmateix, si esteu mantenint molts objectes en viu, la recollida d'escombraries no garanteix que hi hagi prou memòria. Només la memòria disponible es gestionarà de manera eficaç.

Tipus de recollida d'escombraries

Hi ha cinc tipus de recollida d'escombraries que són els següents:

    GC sèrie:Utilitza l'enfocament de marca i escombra per a generacions joves i velles, que és GC menor i major.GC paral·lel:És similar al GC sèrie, excepte que genera N (el nombre de nuclis de CPU del sistema) fils per a la recollida d'escombraries de la generació jove.GC antic paral·lel:És similar al GC paral·lel, excepte que utilitza diversos fils per a les dues generacions.Col·leccionista d'escombrat de marques simultània (CMS):Fa la recollida d'escombraries per a la vella generació. Podeu limitar el nombre de fils al col·lector CMS mitjançant XX:ParalleCMSThreads=opció JVM . També es coneix com a col·lector de pausa baixa simultània.Recollidor d'escombraries G1:Es va introduir a Java 7. El seu objectiu és substituir el col·lector CMS. És un col·lector paral·lel, concurrent i CMS. No hi ha espai de generacions joves i grans. Divideix el munt en diversos munts de la mateixa mida. Primer recull les regions amb menys dades en directe.

Algoritme de marca i escombrat

JRockit JVM utilitza l'algoritme de marca i escombrat per dur a terme la recollida d'escombraries. Conté dues fases, la fase de marca i la fase d'escombrat.

Fase de marca: Els objectes als quals es pot accedir des dels fils, els identificadors natius i altres fonts arrel de GC es marquen com a actius. Cada arbre d'objectes té més d'un objecte arrel. L'arrel GC sempre és accessible. Així, qualsevol objecte que tingui una arrel de recollida d'escombraries a l'arrel. Identifica i marca tots els objectes que estan en ús, i la resta es pot considerar escombraria.

Gestió de memòria en Java

Fase d'escombrat: En aquesta fase, es recorre el munt per trobar el buit entre els objectes vius. Aquests buits es registren a la llista gratuïta i estan disponibles per a l'assignació d'objectes nous.

classe de matemàtiques java

Hi ha dues versions millorades de marcar i escombrar:

    Marca i escombra concurrents Marca i escombrat paral·lels

Marca i escombra concurrents

Permet que els fils continuïn executant-se durant una gran part de la recollida d'escombraries. Hi ha els següents tipus de marcatge:

    Marcatge inicial:Identifica el conjunt arrel d'objectes vius. Es fa mentre els fils estan en pausa.Marcació simultània:En aquest marcatge, se segueix la referència del conjunt arrel. Troba i marca la resta d'objectes vius en un munt. Es fa mentre s'executa el fil.Marcació prèvia a la neteja:Identifica els canvis realitzats mitjançant el marcatge concurrent. Altres objectes vius marcats i trobats. Es fa mentre s'executen els fils.Avaluació final:Identifica els canvis realitzats mitjançant el marcatge de neteja prèvia. Altres objectes vius marcats i trobats. Es fa mentre els fils estan en pausa.

Marca i escombrat paral·lels

Utilitza tota la CPU disponible al sistema per dur a terme la recollida d'escombraries el més ràpid possible. També s'anomena col·lector d'escombraries paral·lel. Els fils no s'executen quan s'executa la recollida d'escombraries paral·lela.

Avantatges de Mark and Sweep

  • És un procés recurrent.
  • És un bucle infinit.
  • No es permeten despeses addicionals durant l'execució d'un algorisme.

Contres de Mark i Sweep

  • Atura l'execució normal del programa mentre s'executa l'algorisme de recollida d'escombraries.
  • S'executa diverses vegades en un programa.