2011-12-06 16 views
12

Estaba leyendo sobre GC en el libro CLR via C#, específicamente sobre cuándo el CLR quiere comenzar una colección. Entiendo que tiene que suspender los subprocesos antes de que se produzca una recopilación, pero menciona que tiene que hacer esto cuando el puntero de instrucción de subprocesos alcanza un punto seguro. En los casos en que no está en un punto seguro, trata de llegar a uno rápidamente, y lo hace por hijacking el hilo (insertando un puntero de función especial en la pila de hilos). Eso está bien y muy bien, pero pensé que los hilos administrados por defecto estaban a salvo.GC Behavior y CLR Thread Hijacking

Inicialmente pensé que podría haberse referido a subprocesos no administrados, pero el CLR permite que los subprocesos no administrados continúen ejecutándose porque cualquier objeto que se utilice debería haber sido anclado de todos modos.

Entonces, ¿qué es un safe point en un hilo administrado, y cómo puede el GC determinar qué es eso?

EDIT:

no creo que estaba siendo lo suficientemente específica. De acuerdo con this MSDN article, incluso cuando se llama a Thread.Suspend, el hilo no se suspenderá hasta que se alcance safe point. Continúa para indicar que un safe point es un punto en una ejecución de subprocesos en el que se puede realizar una recolección de elementos no utilizados.

Creo que no estaba claro en mi pregunta. Me doy cuenta de que un hilo solo puede suspenderse en un punto seguro y deben suspenderse para un GC, pero parece que no puedo encontrar una respuesta clara en cuanto a qué punto seguro es. ¿Qué determina que un punto del código sea seguro?

+2

Seguro por el CLR, no por el CLR. –

Respuesta

13

'' son los puntos de seguridad que nos encontramos:

  1. No en un bloque catch.
  2. No
  3. dentro de un fin
  4. No
  5. dentro de una cerradura
  6. No dentro de la llamada p/invoke'd (en código administrado). No se está ejecutando código no administrado en el CLR.
  7. El árbol de memoria es accesible.

El punto n. ° 5 es un poco confuso, pero a veces el árbol de memoria no se puede recorrer. Por ejemplo, después de la optimización, el CLR puede actualizar un Objeto y no asignarlo directamente a una variable. Según el CG, este objeto sería un objeto muerto listo para ser recolectado. El compilador instruirá al GC cuando esto no ejecute GC todavía.

Aquí hay una entrada de blog en MSDN con un poco más de información: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

EDIT: Bueno, señor, yo estaba equivocado sobre # 4. Consulte here en la sección 'Punto de seguridad'. Si estamos dentro de una sección de código p/invoke (no administrado), entonces puede ejecutarse hasta que vuelva a aparecer en el código administrado.

Sin embargo, de acuerdo con this MSDN article, si estamos en una porción no administrada del código CLR, entonces no se considera seguro y esperarán hasta que el código regrese a administrado. (Estaba cerca, al menos).

+0

Ah, eso tiene mucho sentido, particularmente # 5, toda la estructura de la memoria debe estar en un estado verificable para que el GC ejecute una colección. Es un concepto muy simple cuando tienes la respuesta, era llegar allí con lo que estaba teniendo problemas.¡Gracias! –