Digamos que es un recolector de basura de marcado y barrido concurrente.
Cuando dicho GC maneja punteros constantes, simplemente los recorre (comenzando desde las raíces) y marca cada bloque de datos encontrado. Luego barre todo sin marcar. Un código de cliente debe marcar los bloques de datos que usa como raíces.
¿Pero qué hacer con las variables? Aquí hay una situación:
Ves una variable que almacena un puntero al objetoA.Thread 1leeVy suspende.Thread 2modificaVy hace que apunte al objetoB.- El recolector de basura ejecuta su fase de "marca" y encuentra que
Aya no se hace referencia, luego lo desasigna durante la fase de "barrido". Thread 1despierta e intenta usarA(ya leyóVen el paso 2) marcándolo como root. Y falla , porqueAya no existe.
Entonces, ¿cómo manejar esto?
El Thread 2puede marcar el objeto reemplazado Acon una bandera especial do-no-remove (bandera similar se utiliza para objetos recién asignados). ¿Pero cuándo se debe eliminar esta bandera? Por supuesto que Thread 1podría hacer eso. Pero Thread 2no sabe nada Thread 1y, por lo tanto, no puedo estar seguro de que esto se haga nunca. Esto puede llevar a Aque nunca se libere. Y si GC eliminará esa bandera, entonces nada impide que Ase elimine cuando GC se ejecute por segunda vez ...
Las descripciones del recolector de basura de marca y barrido sobre la marcha que he leído solo mencionan que el objeto reemplazado debe estar "atenuado". Pero sin ningún detalle. Un enlace a una descripción más detallada de la solución sería muy apreciado.