Verigă slabă

În programare , o referință slabă este un tip specific de referință la obiecte create dinamic în sisteme cu colectare de gunoi sau numărare a referințelor . Diferă de referințele puternice prin faptul că colectorul de gunoi nu ține cont de relația dintre referință și obiectul din heap atunci când identifică obiectele de șters. Astfel, o referință slabă vă permite să lucrați cu un obiect ca o referință puternică, dar dacă este necesar, obiectul va fi șters, chiar dacă există o referință slabă la el. Referințele obișnuite sunt uneori denumite referințe „puternice” în contextul colectării gunoiului.  

Conținutul conceptului

Conceptul de referință slabă există în sistemele și limbajele de programare în care este acceptată colectarea gunoiului - eliminarea automată din memorie a obiectelor a căror utilizare a încetat și nu va mai fi reluată. Pentru a determina obiectele care fac obiectul colectării gunoiului, se utilizează una sau alta versiune a algoritmului de accesibilitate - un obiect este considerat accesibil dacă există cel puțin o referință în program. Când nu există nicio referință la un obiect rămas în program, adică utilizarea obiectului a încetat, un astfel de obiect poate fi șters în următorul moment corespunzător.

Mecanismul descris de eliberare a memoriei poate genera în unele cazuri pierderi de memorie din cauza referințelor „uitate”, când referințele la obiecte create sunt stocate în mai multe locuri, iar când obiectul nu mai este folosit, programatorul nu le șterge pe toate. Pentru a evita problemele, programatorul este forțat să adere la o disciplină destul de rigidă în utilizarea legăturilor, ceea ce nu este întotdeauna convenabil.

Pentru a evita astfel de probleme, un limbaj sau mediu de programare poate suporta așa-numitele referințe slabe . Astfel de referințe sunt utilizate în același mod ca referințele obișnuite, dar nu afectează colectarea gunoiului, deoarece nu sunt luate în considerare de mecanismul de numărare a referințelor, iar obiectul la care există astfel de referințe poate fi șters, cu excepția cazului în care există referințe obișnuite la acesta (care în acest context poate fi denumit „legături puternice”).

Implementare și utilizare

În limbajele de programare comune acum, Java și C# , referințele slabe sunt acceptate la nivelul bibliotecilor de sistem. În Java, clasele java.lang.ref.WeakReference și servesc pentru aceasta java.lang.ref.SoftReference, în C#, System.WeakReference.

Procedura de utilizare a referințelor slabe este fundamental aceeași în toate sistemele.

  1. Când este necesară stocarea unei referințe slabe, este creat un obiect referitor (o instanță a clasei WeakReference), căruia îi este transmisă o referință normală („puternică”) obiectului țintă. Referința puternică transmisă este eliberată imediat, iar referrerul stochează o copie a acesteia într-o formă care nu poate împiedica colectorul de gunoi să ștergă obiectul corespunzător. Referentul în sine este salvat ca obiect obișnuit, adică o legătură obișnuită, „puternică” trebuie salvată în el.
  2. Când este necesară utilizarea unei referințe slabe, o metodă get()(în C#, o proprietate Target) este apelată pe referitor, care creează și returnează o referință puternică la obiect dacă acesta încă există, sau un pointer nul null ( nil) dacă obiectul are a fost deja colectat gunoiul.
  3. Dacă referrerul a returnat o referință validă, aceasta este apoi utilizată pentru a accesa obiectul în mod normal. Deoarece get()returnează o referință puternică , obiectul nu va fi șters în timpul utilizării sale. Când utilizarea sa este completă, obiectul la care face referire devine din nou disponibil pentru colectarea gunoiului. Adică, dacă legătura puternică primită de la referrer a fost ștearsă, pentru o nouă utilizare a obiectului, este necesar să se obțină o nouă legătură de la referrer și să se verifice pentru egalitate cu un pointer nul.
  4. Dacă referitorul a returnat un pointer nul , înseamnă că obiectul a fost deja eliminat de către colectorul de gunoi în momentul trimiterii. Codul programului trebuie să gestioneze singur această situație în conformitate cu logica aplicației. De exemplu, o serie de referințe slabe poate acționa ca cache pentru datele accesate frecvent stocate pe medii externe; atunci inaccesibilitatea obiectului printr-o legătură slabă înseamnă nevoia de a-l încărca de pe disc sau din DBMS și actualiza, dacă este necesar, intrarea în cache.

Modul de utilizare a referințelor slabe este determinat de sarcină. O practică comună este de a stoca în colecții referințe slabe la obiecte care sunt necesare doar atâta timp cât aplicația folosește acele obiecte. Atunci când un obiect nu mai este necesar și referințele puternice la acesta sunt eliminate, referințele slabe stocate în colecție nu împiedică scoaterea obiectului din memorie, eliminând astfel necesitatea de a le elimina în mod explicit din colecție.

O caracteristică a clasei SoftReference în Java este că atunci când șterge un obiect, colectorul de gunoi ia în considerare frecvența accesării acestuia prin această referință, ceea ce poate fi util pentru implementarea stocării în cache a datelor situate, de exemplu, pe dispozitive externe - cache-ul colecția deține automat acele obiecte care sunt accesate mai des mai mult timp.

Pentru a preveni ca referințele slabe la obiecte care nu mai există să polueze memoria, bibliotecile de sistem oferă mecanisme care să țină cont de astfel de referințe. O variantă a acestui mecanism sunt cozile de link  - obiecte speciale care sunt transmise referrerului la creare. Când colectorul de gunoi distruge obiectul referit de o referință slabă, plasează o referință la referitorul corespunzător în coada de referință trecută anterior. Astfel, lista referrerilor care conțin link-uri „moarte” este disponibilă programului și le poate șterge în orice moment potrivit.

Link -uri