Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 12807|Răspunde: 0

[JavaSE] Dobândește o înțelegere aprofundată a mecanismului de colectare a gunoiului din Java

[Copiază linkul]
Postat pe 04.12.2017 20:26:51 | | |
1. Semnificația mecanismului de reciclare a gunoiului  
O caracteristică notabilă a limbajului Java este introducerea unui mecanism de colectare a gunoiului, care rezolvă cea mai problematică problemă de gestionare a memoriei pentru programatorii C++, astfel încât programatorii Java nu mai trebuie să ia în considerare gestionarea memoriei atunci când scriu programe. Din cauza mecanismului de colectare a gunoiului, obiectele din Java nu mai au conceptul de "scope", doar referința obiectului are un "scope".Colectarea gunoiului poate preveni eficient pierderea de memorie și poate folosi eficient memoria inactivă.

ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Algoritmi în mecanismele de colectare a gunoiului  
Specificația limbajului Java nu specifică explicit ce algoritm de colectare a gunoiului să fie folosit în JVM, dar orice algoritm de colectare a gunoiului trebuie, în general, să facă două lucruri de bază: (1) să găsească obiecte informaționale inutile; (2) Recuperează spațiul de memorie ocupat de obiecte inutile, astfel încât spațiul să poată fi folosit din nou de program.
1. Colector de numărare a referințelor
1.1 Analiza algoritmilor

Numărătoarea referințelor este o strategie timpurie la colectorii de gunoi. În această abordare, există un număr de referință pentru fiecare instanță a obiectului din heap. Când un obiect este creat și instanța obiectului este atribuită unei variabile, numărul variabilelor este setat la 1. Când orice altă variabilă este atribuită ca referință la acest obiect, numărătoarea se adaugă cu 1 (a = b, apoi contorul instanței obiectului referențiate de b este +1), dar când o referință la o instanță de obiect a depășit durata sa de viață sau este setată la o valoare nouă, contorul de referință al instanței obiectului este scăzut cu 1. Orice instanță a unui obiect cu un contor de referință 0 poate fi colectată ca gunoi. Când o instanță de obiect este colectată de gunoi, contorul de referință al oricărei instanțe de obiect la care face referire este minus 1.
1.2 Avantaje și dezavantaje
Merit:

Colectorul de număr de referințe poate fi executat foarte rapid, integrat în rularea programului. Este avantajos pentru medii în timp real, unde programele nu trebuie întrerupte pentru perioade lungi de timp.
Neajuns:

Referințele circulare nu pot fi detectate. *Dacă obiectul părinte are o referință la un obiect copil, obiectul copil, la rândul său, face referire la obiectul părinte. Astfel, numărul lor de citări nu poate fi niciodată 0.
1.3 Algoritmul de numărare a referințelor nu poate rezolva problema de referință circulară, de exemplu:
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main {    public static void main(String[] args) {        MyObject object1 = new MyObject();        MyObject object2 = new MyObject();        object1.object = object2;        object2.object = object1;        object1 = null;        object2 = null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  
Ultimele două propoziții atribuie obiectul1 și obiectul2 la null, ceea ce înseamnă că obiectele la care sunt indicate obiectul1 și obiectul2 nu mai pot fi accesate, dar pentru că se referă unul la celălalt, contoarele lor de referință nu sunt 0, astfel că colectorul de gunoi nu le va recicla niciodată.
2. Colector de trasare sau algoritmul de marcare și măturare
2.1 Algoritmul de căutare rădăcină


Algoritmul de căutare rădăcină este introdus din teoria grafurilor în matematica discretă, programul consideră toate relațiile de referință ca un graf, pornind de la nodul GC ROOT, căutând nodul de referință corespunzător, după ce găsesc acest nod, continuând să caute nodul de referință al acestui nod, iar când toate nodurile de referință sunt căutate, restul nodurilor sunt considerate noduri nereferențiate, adică noduri inutile.
Java care poate fi folosit ca GC Root
1. Obiecte referențiate în stiva mașinilor virtuale (tabelul variabilelor locale)
2. Obiectul referențiat de atributul static din aria metodei
3. Obiectul referențiat de constanta din aria metodei
4. Obiecte referențiate în stiva locală de metode (obiecte native)
2.2 Diagramă schematică a algoritmului de urmărire

2.3 Analiza algoritmului de eliminare a markerilor

Algoritmul de eliminare a etichetelor scanează din colecția rădăcină, marchează obiectele supraviețuitoare, apoi scanează întregul spațiu pentru obiecte neetichetate de reciclat, așa cum se arată în figura de mai sus. Algoritmul de eliminare a etichetelor nu trebuie să mute obiecte și procesează doar obiectele care nu supraviețuiesc, ceea ce este extrem de eficient atunci când există multe obiecte supraviețuitoare, dar deoarece algoritmul de eliminare a etichetelor reciclează direct obiectele care nu supraviețuiesc, va cauza fragmentarea memoriei.
3. Algoritmul de compactare sau algoritmul de finalizare a etichetării


Algoritmul de finalizare a etichetelor folosește aceeași metodă ca algoritmul de eliminare a etichetelor pentru a eticheta obiectele, dar este diferit la curățare, după ce recuperează spațiul ocupat de obiectele care nu supraviețuiesc, mută toate obiectele supraviețuitoare în spațiul liber de la capătul stâng și actualizează indicatorul corespunzător. Algoritmul tag-finish se bazează pe algoritmul tag-purge și mută obiectele, deci este mai costisitor, dar rezolvă problema fragmentării memoriei. În implementarea colectorilor bazate pe algoritmul de compactare, se adaugă în general tabelele de mânere și mânere.
4. Algoritmul de copiere (colector de compactare)


Algoritmul este propus pentru a depăși costurile suplimentare ale mânerului și a rezolva colectarea gunoiului de resturi heap. Când obiectul este plin, colectarea gunoiului bazată pe algoritmul de copiere scanează obiectul activ din mulțimea rădăcină și copiază fiecare obiect activ pe fața liberă (astfel încât să nu existe găuri libere între memoria ocupată de obiectul activ), astfel încât suprafața liberă să devină fața obiectului, fața originală a obiectului să devină fața liberă, iar programul alocă memoria în fața noii obiecte. O colectare tipică a gunoiului bazată pe algoritmul de coping este algoritmul stop-and-copy, care împarte grămada în fețe de obiect și fețe de arie liberă, iar programul pune pauză execuția în timpul comutării între fețele obiectelor și fețele de arie liberă.
5. Colecționar generațional


Strategia generațională de reciclare a gunoiului se bazează pe faptul căCiclul de viață al diferitelor obiecte este diferit。 Prin urmare, obiectele cu cicluri de viață diferite pot adopta algoritmi diferiți de reciclare pentru a îmbunătăți eficiența reciclării.
Generația tânără
1. Toate obiectele nou generate sunt plasate mai întâi în generația tânără. Scopul generației tinere este să colecteze aceste obiecte cu un ciclu de viață scurt cât mai repede posibil.

2. Memoria noii generații este împărțită într-o regiune Eden și două zone supraviețuitoare (supraviețuitor0, supraviețuitor1) conform raportului 8:1:1. O zonă Eden, două zone Survivor (în general). Majoritatea obiectelor apar în zona Eden. Când zona Survivor0 este și ea plină, zona Eden și zona Survivor 0 sunt copiate într-o altă zonă Survivor1, apoi zona Eden și Survivor0 sunt golite, iar zona Survivor0 este goală, iar zona Survivor0 și Survivor1 sunt schimbate. Adică, să păstreze zona supraviețuitoare1 goală și așa mai departe.

3. Când zona supraviețuitorului 1 nu este suficientă pentru a depozita obiectele supraviețuitoare din Eden și Survivor0, obiectele supraviețuitoare sunt depozitate direct în epoca veche. Dacă bătrânețea este și ea plină, va declanșa un GC complet, adică noua generație și cea veche vor fi reciclate

4. GC-ul noii generații este numit și GC Minor, iar frecvența MinorGC este relativ mare (nu este neapărat declanșată când zona Eden este plină)
Generația veche

1. Obiectele care sunt încă vii după ce au experimentat reciclarea gunoiului N la generația tânără vor fi plasate în generația mai în vârstă. Prin urmare, se poate considera că generația veche este stocată în unele obiecte cu un ciclu de viață lung.

2. Memoria este, de asemenea, mult mai mare decât cea a noii generații (raportul aproximativ este 1:2), când memoria bătrâneții este plină, se declanșează Major GC, adică GC Complet, frecvența Complete GC este relativ scăzută, timpul de supraviețuire al obiectului bătrân este relativ lung, iar pragul ratei de supraviețuire este ridicat.
Generare permanentă
Folosit pentru stocarea fișierelor statice, cum ar fi clase, metode Java etc. Generațiile persistente nu au un impact semnificativ asupra colectării gunoiului, dar unele aplicații pot genera sau apela dinamic anumite clase, cum ar fi Hibernate etc., iar în acest caz, trebuie setat un spațiu de generare persistent relativ mare pentru a stoca aceste noi clase pe durata execuției.
3. GC (Colector de gunoi)Colecționarii folosiți de noua generație: Serial, PraNew, Parallel Scavenge
Colecționarii folosiți de colecționarii de vârstă bătrână: Serial Old, Parallel Old, CMS

Colector serial (algoritm de replicare)
Noua generație de colectoare cu un singur filet, marcaje și curățare sunt cu un singur filet, având avantajul de a fi simple și eficiente.
Colector vechi serial (algoritmul de finisare a etichetei)
Old Age Single Thread Collector, versiunea Old Age a Serial Collector.
Colectorul ParNew (algoritmul stop-copy)
Colectorul de nouă generație poate fi considerat o versiune multi-threaded a colectorului Serial, care are performanțe mai bune decât Serial într-un mediu CPU multi-core.
Colector paralel de scavenge (algoritm stop-copy)
Colectoare paralele pentru un debit ridicat și utilizare eficientă a procesorului. Debitul este în general de 99%, iar debitul = timp de thread de utilizator / (timp de thread de utilizator + timp de thread GC). Este potrivit pentru scenarii precum aplicații de fundal care nu necesită interacțiune ridicată corespunzător.
Colector vechi paralel (algoritm stop-copy)
O versiune mai veche a Parallel Scavenge Collector, un colector paralel, cu prioritate de debit
Colector CMS (Concurent Mark Sweep) (Algoritmul Mark-Clean)
Concurență mare, pauză mică, urmărirea celui mai scurt timp de pauză la recuperarea GC, utilizare mare a CPU-ului, timp de răspuns rapid, timp scurt de pauză și CPU multi-core care urmărește un timp de răspuns ridicat
4. Mecanismul de implementare al GCDeoarece obiectul a fost procesat în generații diferite, zona și momentul colectării gunoiului sunt de asemenea diferite. Există două tipuri de GC: GC Scavenge și GC complet.
Scavenge GC
De obicei, când un obiect nou este generat și nu aplică pentru spațiu în Eden, GC-ul Scavenge va fi declanșat, care va GC zona Eden, va elimina obiectele nesupraviețuitoare și va muta obiectele supraviețuitoare în zona Supraviețuitorului. Apoi rezolvă cele două zone din Survivor. GC-ul se realizează astfel în zona Eden a generației tinere și nu afectează generația mai în vârstă. Deoarece majoritatea obiectelor pornesc din zona Eden, iar zona Eden nu este alocată foarte mult, GC-ul zonei Eden este realizat frecvent. Prin urmare, este în general necesar să se folosească algoritmi rapizi și eficienți pentru a face Eden liber cât mai curând posibil.
GC complet
Organizează întregul teanc, inclusiv pentru tineri, titulari și permanenti. Full GC este mai lent decât Scavenge GC pentru că necesită reciclarea întregului heap, așa că numărul de GC-uri Full ar trebui redus cât mai mult posibil. O mare parte din procesul de tuning JVM este acordarea FullGC. GC-ul complet poate fi cauzat din următoarele motive:
1. Titularizarea este scrisă integral
2. Perm se scrie complet  
3. System.gc() este afișat ca un apel  
4. Strategia de alocare a domeniului Heap se schimbă dinamic după ultimul GC
5. Java cu GC va avea, de asemenea, probleme de scurgere de memorie1. Utilizarea claselor statice de colectare precum HashMap, Vector etc. este cea mai predispusă la pierderi de memorie, iar ciclul de viață al acestor variabile statice este același ca cel al aplicației, iar toate obiectele nu pot fi eliberate, deoarece vor fi întotdeauna aplicate de Vector și alții.
Vector static v = vector nou(); pentru (int i = 1; i<100; i++) { Object o = new Object();     v.add(o);     o = nul; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  
În acest exemplu, există o referință v pentru obiectul Vector și o referință o pentru obiectul Object în stiva de coduri. În bucla For, generăm obiecte noi, apoi le adăugăm la obiectul Vector și apoi anulăm referința o. Întrebarea este: când referința O este anulată, dacă apare GC, obiectul Object pe care l-am creat poate fi reciclat de GC? Răspunsul este nu. Pentru că atunci când GC urmărește referințele în stiva de cod, găsește v referințe, iar dacă continui să urmărești, vei descoperi că există referințe la obiecte Object în spațiul de memorie către care sunt indicate de v referințe. Aceasta înseamnă că, deși referința o a fost golită, există totuși alte referințe la obiectul Obiect care pot fi accesate, astfel încât GC-ul nu le poate elibera. Dacă după această buclă, obiectul Object nu are efect asupra programului, atunci presupunem că programul Java are o scurgere de memorie.
2. Diverse conexiuni, conexiuni de bază de date, conexiuni de rețea, conexiuni IO etc. nu arată apelul aproape de închidere și nu sunt reciclate de GC, ceea ce duce la scurgeri de memorie.
3. Utilizarea ascultătoarelor poate cauza, de asemenea, pierderi de memorie atunci când ascultătorul nu este șters în timpul eliberării obiectului.




Precedent:Începătorii joacă ceva tehnologie neagră în CSS
Următor:Atenție la virusul software Wanke Cloud snap!
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com