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.
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