practico examen certificacion c# garbage-collection dispose idisposable

practico - examen de certificacion c#



Preguntas sobre la pérdida de memoria (3)

¿Cuál es el alcance de su lista de arrays estática? Me parece que tiene un alcance de formulario. Si es así, no se eliminará ya que los objetos estáticos siempre se consideran rooteados y tienen una vida útil de la aplicación. En mi experiencia, la estática siempre toma más memoria y es promovida a gen 2 por este hecho. Si tiene alguna duda, tome un analizador de memoria .net y compruébelo. También puede tomar volcados de memoria y analizarlos usando windbg para descubrir la causa real de la fuga.

He leído mucho sobre esto desde que me pidieron que arregle una aplicación C # que tiene problemas de pérdida de memoria, pero no he encontrado una respuesta para estos 2 problemas:

Considera el siguiente código:

private static ArrayList list = new ArrayList(); public void Function() { list.add(object1); list.add(object2); //didn''t call clear() prior to reusing list list = new ArrayList(); }

Dado que la lista no fue borrada antes de crear una nueva, ¿generará algún tipo de basura que no será liberada después de que la propia lista está dispuesta?

El segundo problema es con respecto a Form.Dispose (). Veo que muchos controles disponibles en la vista del diseñador (es decir, etiquetas, cuadros de imagen) requieren eliminación. Parece que llamar a Dispose () en un Form causa que todos estos tipos de controles se eliminen también (corríjanme si estoy equivocado), lo cual es extraño ya que el diseñador agrega un método anulado Dispose (bool disposing) anulado que lo hace no tal cosa. Supongo que esto sucede en el método Dispose (bool disposing) vacío de la clase de formulario base.

El problema con lo anterior es que no tengo muy claro qué hacer para garantizar que todos los recursos del Formulario se eliminen correctamente. No entiendo cómo la Forma sabe qué objetos necesita eliminar. Por ejemplo, si en mi formulario tengo un campo que es un objeto ID identificable personalizado, ¿el formulario sabrá que necesita deshacerse? ¿O debería agregar el código necesario para liberar el objeto yo mismo?

Además, si necesito agregar el código para eliminar ciertos objetos, ¿cómo trato el hecho de que el diseñador ya ha anulado el método Dispose (bool disposing) vacío ? ¿Debo editar el código generado por el diseñador o hay una manera más clara de hacerlo?

Espero que esto no sea confuso, es un poco difícil de explicar. Gracias


No, eso no es una filtración. Cuando el recolector de elementos no utilizados busca referencias de objetos, ya no encontrará una referencia al ArrayList original. Lo reemplazaste Por lo tanto, destruirá automáticamente ese objeto ArrayList original, así como todos sus elementos, si tampoco se mencionan en ninguna parte.

La clase Form sabe cómo deshacerse de sí misma, así como todos los controles que son ventanas secundarias en ese formulario. Esto sucede cuando el usuario cierra el formulario, el mensaje WM_CLOSE que envía Windows activa este código. La colección Form.Controls lo ayuda a encontrar la referencia a todos los controles secundarios para que pueda eliminarlos también.

Sin embargo, esto no sucederá si elimina los controles del formulario usted mismo. Ahora depende de usted llamar a Dispose () sobre ellos. En particular, el método Controls.Clear () es peligroso. Lo que es inusual es que esto causa una fuga permanente, los controles que elimina se mantienen vivos por la ''ventana de estacionamiento''. Lo que mantiene vivo el identificador de ventana para que pueda moverlo a otra parte, en otra ventana de contenedor, por ejemplo. Si no los mueves, permanecerán alojados en esa ventana de estacionamiento para siempre. Ninguna otra clase en el marco se comporta de esta manera.

Esta pérdida es fácil de diagnosticar con Taskmgr.exe, pestaña Procesos. Ver + Seleccionar columnas y marcar Objetos de USUARIO. Si esto aumenta constantemente mientras tu programa se ejecuta, entonces estás perdiendo controles.


En muchos marcos de administración de memoria, recogidos de forma innecesaria y de otro modo, la liberación de memoria dentro de una aplicación generalmente no hace que la aplicación libere esa memoria, sino que registra el hecho de que la memoria debe estar disponible para futuras solicitudes. Parte de la idea detrás de la recolección de basura es que cuando el código de usuario solicita memoria y la aplicación sabe que tiene al menos esa cantidad disponible inmediatamente, ni el código ni la aplicación se preocuparán si se asigna "memoria" no necesaria para esa solicitud. o "libre". Cuando la última referencia alcanzable a un objeto se destruye o se vuelve inalcanzable, el objeto deja de existir en ese momento, pero generalmente no hay mucho propósito en tratar de reclamar la memoria usada anteriormente por objetos inexistentes hasta que dicha recuperación sea requerida para Cumplir con una solicitud de asignación, o la relación "memoria liberada por tiempo invertido" es tan buena como es probable que obtenga.

Tenga en cuenta que para que el sistema recupere la memoria asociada a un objeto, es absolutamente imperativo que no exista ninguna referencia de ningún tipo a ese objeto. Si existen referencias débiles accesibles a un objeto que no se puede alcanzar de otra manera, el recolector de basura debe invalidar todas las referencias (para que ya no identifiquen el objeto) antes de que el espacio utilizado por el objeto pueda recuperarse. Si un objeto inalcanzable tiene un finalizador registrado, el sistema debe poner el objeto en una cola de cosas que necesitan una finalización inmediata (lo que lo hace inelegible para la recuperación) y anular el registro del finalizador.

Las referencias débiles y las referencias utilizadas para la finalización son invalidadas automáticamente por el GC cuando se abandonan todas las demás referencias a un objeto y, por lo tanto, no causan pérdidas de memoria. Sin embargo, hay otro tipo de referencia que puede causar filtraciones desagradables : suscripciones de eventos de los editores que sobreviven a los suscriptores. Si el objeto A se suscribe a un evento del objeto B, el objeto A no se puede recolectar como basura a menos que (1) se anule la suscripción del evento o (2) B sea elegible para la recolección de basura. Me encuentro desconcertado por qué Microsoft no incluyó algunos medios de cancelación automática de eventos, pero no lo hicieron.