|
|
Ya había hablado del Garbage Collector aquí antes, pero me surgieron dudas existenciales sobre que pasa con una clase y sus relacionadas cuando se trata de una composición y cuando se trata de una agregación, que pasa con los hijos… con los nietos… y cuestiones varias como ¿y si se intenta destruir un hijo cuyo padre esta desreferenciado pero el GC aún no lo ha recolectado? ¿mantendría esta situación al hijo “vivo” hasta la siguiente recolección? etc… las típicas cosas que te hacen comerte la cabeza, así que decidí hacer unos experimentos |
En principio, cuando una relación entre dos objetos es de composición, digamos que el hijo no puede vivir sin el padre, por lo que al destruir el padre ha de destruirse el hijo; cuando se trata de una relación de agregación, el hijo puede subsistir sin el padre ya que podría pertenecer a más relaciones ó simplemente ser un objeto independiente. Pero, estos dos conceptos son únicamente inherentes al diseño, en la práctica un objeto es un objeto y si no existe una referencia a él en ningún sitio es candidato a ser destruido por el GC, da igual de que color pintases la flecha en el diagrama UML xD.
Para las pruebas usaré esta sencilla clase de nodo, que permite ponerle un nombre, añadir más subnodos e indica en la consola cuando es destruida la instancia, que nombre tiene y en que generación ha sido:
|
class Nodo
} |
Si creo un arbol de nodos y a continuación desreferencio al padre…
|
Nodo Padre = new Nodo(“Padre”); |
Sucede que todos son destruidos:
| Destruyendo Hijo 2 en generación 0 Destruyendo Padre en generación 0 Destruyendo Nieto 3 en generación 0 Destruyendo Nieto 2 en generación 0 Destruyendo Nieto 1 en generación 0 Destruyendo Hijo 3 en generación 0 Destruyendo Hijo 1 en generación 0 |
Pero, si creo una referencia a por ejemplo el “Nieto 1”…
|
Nodo Padre = new Nodo(“Padre”); Nodo Nieto1 = Padre.Items[0].Items[0]; Padre = null; |
Sucede que ese nodo en concreto no es recolectado, independientemente de que la clase que lo contenía haya desaparecido ya.
| Destruyendo Nieto 2 en generación 2 Destruyendo Hijo 3 en generación 2 Destruyendo Hijo 2 en generación 2 Destruyendo Hijo 1 en generación 2 Destruyendo Padre en generación 2 Destruyendo Nieto 3 en generación 2 |
Esto se extiende a cualquier tipo de objeto, no solo a los que están en colecciones. Por ejemplo, creo una nueva clase que pueda monitorizar su destrucción:
|
class TestClass
} |
La añado como miembro a la clase Nodo, quedando de esta forma:
|
class Nodo
} |
Si ejecuto de nuevo el primer ejemplo, todo se destruye:
| Destruyendo nodo Hijo 2 en generación 1 Destruyendo TestClass Nieto 1 en generación 1 Destruyendo nodo Nieto 1 en generación 1 Destruyendo TestClass Hijo 3 en generación 1 Destruyendo nodo Hijo 3 en generación 1 Destruyendo TestClass Hijo 2 en generación 1 Destruyendo TestClass Hijo 1 en generación 1 Destruyendo nodo Hijo 1 en generación 1 Destruyendo TestClass Padre en generación 1 Destruyendo nodo Padre en generación 1 Destruyendo TestClass Nieto 3 en generación 1 Destruyendo nodo Nieto 3 en generación 1 Destruyendo TestClass Nieto 2 en generación 1 Destruyendo nodo Nieto 2 en generación 1 |
En conclusión, el algoritmo de optimización de memoria del GC contempla estas situaciones, y todo lo que no pueda ser accedido ya sea de forma directa ó indirecta es recolectado.
Hasta el próximo capítulo de “El Garbage Collector y tu”

La conclusión es simple, si el GC sale de caza y todos se han olvidado de ti… ó los que se acuerdan de ti ya nadie se acuerda de ellos… te come el GC (que trágica es la vida de un objeto en .Net 






[...] puestos en temas del GC, hablemos del patrón desechable, que aunque nos permite crear clases que sean de usar y tirar… [...]
Pingback por vtortola : El patrón desechable con la interfaz IDisposable — Julio 17, 2007 @ 7:19 pm
[...] puestos en temas del GC, hablemos del patrón desechable, que aunque nos permite crear clases que sean de usar y tirar… [...]
Pingback por El patrón desechable con la interfaz IDisposable - vtortola — Julio 17, 2007 @ 7:24 pm