Tengo una variable de bucle que no parece estar recibiendo basura recolectada (de acuerdo con el perfilador de memoria ANTS Red - Gate) a pesar de haber salido del alcance.Variable de bucle que no se recopila
El código es como la siguiente:
while (true)
{
var item = blockingQueue.dequeue(); // blocks until an item is added to blockingQueue
// do something with item
}
Por lo que yo puedo decir, una referencia a item
permanece hasta blockingQueue.dequeue()
devoluciones. ¿Es este el comportamiento previsto, o podría ser un error en el generador de perfiles de memoria?
En segundo lugar, si este es el comportamiento previsto, ¿cómo forzaría item
para recoger en el extremo del cuerpo del bucle? Establecerlo en null
no parece hacer que se recopile. Esto es importante ya que la cola podría bloquearse durante un tiempo prolongado y item
hace referencia a un árbol de objetos bastante grande.
Nota: la documentación del generador de perfiles indica que se realiza un GC antes de tomar una instantánea de memoria y que la referencia no se encuentra en la cola del finalizador.
Pude reproducir el mismo problema con el código here.
actualización
El código en lo esencial fue un poco defectuoso, ya que legítimamente se aferró a una referencia en GetFoo()
. Después de haberlo cambiado, el objeto hace ahora se recoge cuando se establece explícitamente en null
. Sin embargo, creo que la respuesta de Hans explica la situación que estoy viendo en mi código actual.
hace otra cosa tienen una referencia a él? –
¿Puede mostrar todos los usos del artículo? –
El generador de perfiles muestra referencias al objeto de las raíces de GC y este es uno de ellos. El ejemplo que publiqué en github muestra el problema y allí la referencia * solo * está dentro del ciclo. – SimonC