Salutare!
Astăzi vom încerca să vorbim puțin despre referințe strong vs referințe soft în Java. În plus, vă voi prezenta și un caz în practică în care am folosit noțiunea de referințe soft, în mai mult de 7 ani de programare în Java.
În primul rând, haideți să ne amintim de conceptul de referință strong. Ce înseamnă să ai o referință strong la un obiect în Java? Răspunsul este cât se poate de simplu: înseamnă că obiectul respectiv nu va fi niciodată colectat de către GC (garbage collector). Nici măcar dacă aplicația respectivă nu va mai avea memorie disponibilă!
Pe de altă parte, conceptul de referință soft la un obiect, înseamnă că acel obiect este eligibil pentru a fi colectat de garbage collector, doar în momentul în care este nevoie ca memoria RAM să fie eliberată, adică când JVM-ul rămâne fără memorie. Pe lângă aceste două tipuri există și weak și phantom references. Pe acestea, nu le voi tratat în acest articol.
Acum când am înțeles cele două concepte, haideți să vedem și un exemplu practic în care am folosit al doilea concept: cel de referință soft. Ca și o mică paranteză, referințe strong se tot folosesc în viața unui programator. Nici nu mai are rost să prezentăm un exemplu, în acest sens.
Revenind. Când am folosit eu referințe soft? Păi când am construit un tool de alerte și când am avut nevoie să păstrez niște date în cache. Pentru fiecare alertă, pornind de la un șablon, ofeream o descriere personalizată a alertei respective. Ce face, cum face i mai ales ce trebuie investigat atunci când alerta respectivă se ridică. Operația de construire a descrierii pe baza șablonului dura câteva milisecunde bune. În loc să îl construiesc de fiecare dată când un utilizator vroia să îl vadă, am preferat să îl construiesc o dată și apoi să păstrez o referință soft către acesta și să refolosesc descrierea respectivă. Ca un fel de cache… De ce nu mi-am permis să folosesc referințe strong? Pentru că era multe tipuri de alerte și nu vroiam să consum 50% din memoria maximă a heap-ului pentru a le stoca. De ce referințe soft? În cazul în care utilitarul are nevoie de ceva mai multă memorie, poate elibera aceste obiecte cache-uite. În momentul în care utilizatorul final are nevoie din nou de ele, le putea construi din nou.
Cu alte cuvinte, avem un sistem de caching cu un mecanism de eviction bazat pe momentul în care JVM-ul are nevoie de memorie volatilă. Simplu, ușor, intuitiv.
Voi ați folosit vreodată referințe soft în viața voastră de programatori? 🙂
PS: Nu uitați să creați obiectele de tip string cu new, dacă doriți să nu ajungă în pool-ul de string-uri și să vă treziți că aceste obiecte nu sunt colectate de GC.