Diciamo che è un garbage collector simultaneo mark-and-sweep.
Quando tale GC gestisce puntatori costanti, li attraversa (iniziando dalle radici) e contrassegna tutti i blocchi di dati rilevati. Quindi spazza tutto senza segno. Un codice client deve contrassegnare i blocchi di dati che utilizza come root.
Ma cosa fare con le variabili? Ecco una situazione:
-
Vè una variabile, che memorizza un puntatore all'oggettoA. -
Thread 1leggeVe sospende. -
Thread 2modificaVe fa puntare all'oggettoB. - Il garbage collector esegue la sua fase di "mark" e rileva che
Anon viene più referenziato, quindi lo rilascia durante la fase di "sweep". -
Thread 1si sveglia e tenta di utilizzareA(già letto daVal passaggio 2) contrassegnandolo come root. E fallisce , perchéAnon esiste più.
Quindi, come gestirlo?
Il Thread 2 può contrassegnare l'oggetto sostituito A con uno speciale flag di non rimozione (il flag simile è usato per gli oggetti appena assegnati). Ma quando questa bandiera dovrebbe essere rimossa? Ovviamente Thread 1 potrebbe farlo. Ma Thread 2 non sa nulla di Thread 1 , e quindi non può essere sicuro che questo verrà fatto sempre. Questo potrebbe portare a A non verrà mai liberato. E se GC rimuoverà quel contrassegno, nulla impedisce che A venga rimosso quando GC viene eseguito per la seconda volta ...
Le descrizioni dei garbage collector mark-and-sweep al volo che ho letto ricordano solo che l'oggetto sostituito dovrebbe essere "grigio". Ma senza dettagli. Un link ad una descrizione più dettagliata della soluzione sarebbe molto apprezzato.