2009-06-11 14 views
21

He leído muchos artículos de rendimiento de .NET que describen la recolección de basura Gen1, Gen2 y objetos que sobreviven a las generaciones.Recolección de basura en .NET (generaciones)

¿Por qué los objetos sobreviven a la colección?

¿Qué es fijar?

¿Cómo puedo obtener más información al respecto?

+2

Se obtiene una copia de CLR a través de C# y lea el capítulo de recolección de basura. Es un tema levemente carnoso: aprender de un foro en línea. – Gishu

Respuesta

0

This es un interesante artículo sobre el tema que puede encontrar informativo.

0

La fijación se utiliza para evitar que el recolector de basura reubique objetos. Puede perjudicar el rendimiento al restringir lo que el recolector de basura puede hacer. En general, los objetos fijados deben ser fijados por el menor tiempo posible.

29

Una razón por la que tiene varias generaciones en un recolector de basura es para evitar perder memoria debido a la fragmentación.

Cada llamada a la función puede significar la creación y eliminación de colección de objetos múltiples, por lo que el montón de memoria para su programa tiende a fragmentarse muy rápidamente. Esto deja huecos que no son muy útiles. El resultado es que su programa necesita ser periódicamente fragmentado, al igual que un disco duro. Esto es parte de lo que sucede durante una colección.

Cuando un objeto sobrevive a una colección, se traslada a una generación de mayor duración con la teoría de que si sobrevivió a una colección, probablemente sobrevivirá a otras. Por lo tanto, las generaciones posteriores tienen menos vuelco y no se fragmentan tanto. Esto significa que su programa pasa menos tiempo malabarizando las cosas para limpiar agujeros y desperdicia menos memoria. Esto también mejora la gestión de la memoria tradicional (malloc/free o new/delete), lo que deja al sistema operativo la tarea de administrar cualquier fragmentación de memoria.

La razón por la que un objeto sobrevive a la recopilación es porque hay algo en algún lugar que todavía está "dentro del alcance" y contiene una referencia a ese objeto. Hay algunas maneras en que puede hacer que esto ocurra y luego olvidarse de la referencia, por lo que es posible "perder" la memoria en el código administrado.

A veces la gente tiene la tentación de llamar al GC.Collect() en un esfuerzo para que el recolector de basura limpie algo. Tal vez descubrieron que tienen una filtración, o piensan que la memoria se está volviendo demasiado fragmentada. Debes resistir esos impulsos. Si bien la recolección de basura en .Net no es perfecta, es muy bueno, y es casi seguro que es mucho mejor para limpiar la memoria que usted. Las probabilidades son que si un objeto puede y debe ser recolectado, será. Recuerde que llamar al GC.Collect() puede empeorar las cosas al ayudar al recolector de basura a mover objetos hasta una generación más alta, y así mantenerlos por más tiempo de lo que lo estarían.

En cambio, si sospecha que tiene una fuga, busque en su propio código algo así como una variable global o estática que pueda contener una referencia a muchos otros elementos. La única vez que debe llamar al GC.Collect() es cuando tiene información sobre la naturaleza del programa que no está disponible para el recolector de basura, y eso es bastante raro ya que el GC conoce todas las referencias que ha creado.

"Fijar" es para cuando necesita pasar un objeto a una biblioteca no administrada.El recolector de elementos no utilizados puede mover la ubicación física de un objeto en la memoria, por lo que debe "fijarla" en un lugar o el puntero utilizado por la biblioteca no administrada podría quedar invalidado. No se puede recopilar un objeto inmovilizado, por lo que no debe anclar un objeto más de lo necesario.

+0

cuando dices GC in. NO es perfecto, ¿qué es lo que no te gusta? Me interesa saber, ya que esto nos ayuda a mejorarlo. Gracias – mfawzymkh

+0

Nada en particular, de su descripción de perfil Sospecho que usted sabe mucho más sobre eso que yo. Digo "no perfecto" en el sentido de que "nada es perfecto" y es tan falible como cualquier software. Si realmente quieres romperlo, puedes encontrar la manera. –

+0

Actualicé la publicación para que la línea no se destaque tanto ... esto lentamente se está convirtiendo en una respuesta más larga. –

10

http://blogs.msdn.com/maoni/ es un buen recurso.
Hacer preguntas aquí también ayuda :)

Para sus preguntas:

¿Por qué objetos sobreviven la colección:
objetos sobreviven una colección cuando son "objetos vivos", o "objetos al alcance". objetos alcanzables son objetos donde hay una referencia a ellos de otro objeto que se encuentra en:

  1. La pila
  2. La cola de finalización
  3. otro objeto en una generación más alta (por ejemplo, un objeto Gen2 sostiene una referencia a un objeto Gen0)
  4. la tabla de identificador (una estructura de datos utilizada por el CLR, y requieren una entrada independiente en su propio :))

lo que se Fijación:
Fijar significa asegurarse de que el objeto no se mueva en la memoria. los objetos se mueven en la memoria como resultado de una compactación de GC, puede crear un GCHandle de tipo pinned si desea fijar un objeto, la fijación también ocurre automáticamente detrás de la exploración para los objetos que se pasan al código nativo mediante PInvoke (como cadenas que son pasado como salida, el búfer interno se fija durante la llamada a PInvoke).

Consulte http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx para obtener un buen ejemplo sobre GCHandle.

+0

Para mi propia iluminación: ¿Sería correcto decir que los objetos "fijados" viven en la mesa de manejo? –

+0

:) Cuando crea un GCHandle, se almacena en la tabla de identificador, que se utiliza como una de las fuentes para descubrir objetos vivos. , por lo tanto, los GCHandle fijados y no fijados se almacenan allí. – mfawzymkh

Cuestiones relacionadas