york tirar tiradero servicio sacar recolección reciclaje que para new madera lugares escombros donde dias debe construccion cerca basura c# garbage-collection weak-references

c# - tirar - ¿Cuáles de estos objetos son elegibles para la recolección de basura?



servicio de recolección de basura (4)

Esta es una pregunta que me formularon recientemente en mi entrevista: ¿Qué objeto (s) ''aleatorio'' se recopilarían durante la llamada ''GC.Collect ()''?

String a = new Random().Next(0, 1) ==1 ? "Whatever 1" : "Whatever 2"; String b = new WeakReference(new Random()).Target.Next(0, 1) == 1 ? "Whatever 1" : "Whatever 2"; GC.Collect();

Respondí que esta es una pregunta específica de la implementación y depende en gran medida de la implementación del GC y la correspondiente semántica de referencia débil. Hasta donde yo sé, la especificación C # no proporciona una descripción exacta de lo que debe hacer GC.Collect y cómo deben manejarse las referencias débiles.

Sin embargo, mi entrevistador quería escuchar algo más.


Ambas instancias Random() y WeakReference son elegibles para la recopilación:

  • El primer Random no se almacenó en un local, y mucho menos en un local que luego se lee.
  • El segundo Random se pasó a WeakReference , por lo que estaría bien recopilar de todos modos , pero WeakReference no se realiza en ningún lado, por lo que también es elegible para la recopilación.

Ninguna de las cadenas son (solo hay 2 instancias de cadena aquí, no 4, incluso si se alcanzó cada posible ruta de código): como son literales en el código c #, se internan una vez que existen.


Es cierto que esto depende de la implementación (y del compilador). Si todo esto está en el mismo método, no puede saber qué objetos están todavía en la pila . Ya que los objetos en la pila todavía se referencian no serían coleccionables.

Lo que el entrevistador más deseaba que hiciera es verificar qué objetos son aún accesibles a la llamada de GC. Recoja asumiendo una implementación "perfecta" que lo descarte todo lo antes posible.


GC.Collect es como en Java equivalente a System.gc ()

"Recomienda" verificar valores nulos para eliminarlos. Realmente no se puede depender de esta característica ya que es muy automática a diferencia de C ++.

¡Espero eso ayude!


Sin embargo, mi entrevistador quería escuchar algo más.

Espero que quieran escuchar una respuesta como la que Marc Gravell ha publicado aquí, pero que se basa en un modelo demasiado simplificado de cómo funcionan las máquinas virtuales recolectadas con basura que no se parecen a la realidad.

Por ejemplo, la llamada a GC.Collect podría optimizar el GC.Collect llamada, en cuyo caso no hay raíces globales, por lo que todos los bloques asignados al montón se recopilan. O el compilador puede crear una nueva entrada en el marco de la pila para cada elemento temporal (no solo las variables en el código fuente) que mantiene todo accesible y no se recoge nada. O el compilador puede intercambiar el orden de la creación de las cadenas a y b y recoger el objeto Random referido por WeakReference antes de WeakReference el método Target causando una excepción de referencia null para que el otro Random nunca se asigne.