¿Cómo maneja un recolector de basura concurrente las variables?

8

Digamos que es un recolector de basura de barrido y marcado concurrente.

Cuando este GC maneja los punteros constantes, simplemente los recorre (comenzando desde las raíces) y marca todos los bloques de datos encontrados. Luego barre todo sin marcar. Un código de cliente debe marcar los bloques de datos que utiliza como raíces.

¿Pero qué hacer con las variables? Aquí hay una situación:

  1. V es una variable que almacena un puntero al objeto A .
  2. Thread 1 lee V y suspende.
  3. Thread 2 modifica V y hace que apunte al objeto B .
  4. El recolector de basura ejecuta su fase de "marca" y encuentra que A ya no está referenciado, luego lo desasigna durante la fase de "barrido".
  5. Thread 1 despierta y trata de usar A (ya leído de V en el paso 2) marcándolo como root. Y falla , porque A ya no existe.

Entonces, ¿cómo manejar esto?

El Thread 2 puede marcar el objeto reemplazado A con un indicador especial de no quitar (el indicador similar se usa para los objetos recién asignados). Pero cuando esta bandera debe ser eliminada? Por supuesto Thread 1 podría hacer eso. Pero Thread 2 no sabe nada acerca de Thread 1 , y por lo tanto no podemos estar seguros de que esto se hará nunca. Esto puede provocar que A nunca se libere. Y si GC eliminará esa bandera, entonces nada impide que A se elimine cuando GC se ejecute por segunda vez ...

Las descripciones sobre el 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 dato específico. Un enlace a una descripción más detallada de la solución sería altamente apreciado.

    
pregunta lorus 06.03.2013 - 04:39

2 respuestas

4

Dependiendo de los detalles precisos de la implementación del recolector de basura, es posible que esto no sea un problema en su paso 4. Por ejemplo, en el paso 2, el subproceso 1 lee probablemente V en un registro. Es probable que el recolector de basura deba examinar el contenido de los registros de todos los subprocesos activos (en ejecución y suspendidos) para ver si hay una referencia a algún objeto que se encuentre en los registros.

Inevitablemente, la implementación de un recolector de basura está estrechamente relacionada con el entorno operativo (y de subprocesamiento) en el que se ejecuta. Existen muchas técnicas de implementación para garantizar que se consideren todas las referencias almacenadas y transitorias.

    
respondido por el Greg Hewgill 06.03.2013 - 04:53
0

Tienes que marcar las variables locales en algún momento durante la fase de marca. Todas las variables locales, incluidas las que normalmente viven en la pila. De alguna manera.

Además, creo que se debe hacer durante la fase síncrona (todos los mutadores se detuvieron) de escanear objetos modificados. De hecho, el mismo problema puede surgir incluso sin tener en cuenta los registros / variables locales. Considere el objeto A apuntando a nulo y el objeto B apuntando a C. Ahora escanea el objeto A, viene un hilo mutador, copia la referencia a C de B a A, anula a B y ahora pasa a escanear a B. Y C resbaló bajo tus dedos.

No conozco ninguna forma de lidiar con esto que no implique detener a los mutadores. La técnica habitual es al final de la fase de marca para detener todos los mutadores y volver a marcar todos los objetos que mutaron durante la fase de marcado principal. E incluir pilas y registros en eso.

La marcación de los registros se trabaja normalmente al hacerlo de forma sincrónica al llamar al recopilador en el hilo a veces. Dentro de la función de recopilador, solo sus propias variables locales (que no son raíces) pueden estar en los registros, todas las demás variables locales en la cadena de llamadas están en la pila, por lo que puede recorrer la pila.

Alternativamente, puedes enviar una señal al hilo. El manejador de señales volverá a forzar todas las variables en la pila, para que pueda recorrerlas. La desventaja de este método es que depende de la plataforma.

    
respondido por el Jan Hudec 06.03.2013 - 09:15

Lea otras preguntas en las etiquetas