¿Cuál es la diferencia entre los recursos gestionados y los nativos a la hora de disponer? (.NETO)


Estaba leyendo el artículo de MSDN sobre cómo implementar identificable y no estoy seguro de la diferencia entre recursos administrados y nativos citados en el artículo.

Tengo una clase que debe disponer 2 de sus campos cuando se dispone. ¿Debo tratarlos como recursos Administrados (disponer solo cuando disponer = true) o nativos?

Author: Deduplicator, 2009-01-29

3 answers

Un recurso administrado es otro tipo administrado, que implementa IDisposable. Necesitas llamar a Dispose() en cualquier otro tipo IDisposable que utilices. Los recursos nativos son cualquier cosa fuera del mundo administrado, como los controladores nativos de Windows, etc.


EDITAR: Respuesta a la pregunta en el comentario (demasiado largo para comentar)

No es solo un tipo administrado. Un tipo correctamente construido, que no implemente IDisposable será manejado por el recolector de basura y no tendrá que hacer nada más. Si su tipo usa un recurso nativo directamente (por ejemplo, llamando a bibliotecas Win32), debe implementar IDisposable en su tipo y deshacerse del recurso(s) en el método Dispose. Si su tipo utiliza un recurso nativo encapsulado por otro tipo que implementa IDisposable, debe llamar a Dispose() en instancias de este tipo en el método Dispose de su tipo.

 18
Author: Brian Rasmussen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-30 06:29:20

Para añadir un poco a la respuesta de Brian, y tu comentario/pregunta:

La diferencia entre un recurso Administrado/No Administrado es que el Recolector de basura es consciente de los recursos administrados y no es consciente de los recursos no administrados. Sé que la respuesta no es muy concreta, pero la diferencia es enorme.

Para ayudar a dibujar la línea en la arena aquí está la versión corta (y probablemente plagada de pequeños errores) de cómo GC se ejecuta y limpia la memoria:

El recolector de basura es consciente de todo objetos administrados, pero cuando se ejecuta la recolección de basura, inicialmente no sabe si algún objeto dado todavía está en uso o es elegible para ser liberado. Determina si puede o no limpiar un objeto marcando inicialmente todos los objetos como basura, luego recorriendo desde la raíz de la aplicación a todos los objetos referenciados. Cada objeto que tiene una relación con la raíz (una referencia, ya sea directa o indirecta) se marca como accesible y ya no se considera basura. Después de que el GC se ejecuta a través de cada objeto accesible limpia el resto ya que ya no están en uso.

En casi todos los casos en los que se trabaja con objetos de.NET framework, puede estar seguro de que los objetos están administrados (. NET proporciona envoltorios administrados de casi todos los recursos no administrados para garantizar que se limpien correctamente); otros componentes de terceros que se conectan a la API Win32 (o sus componentes que lo hacen) son los objetos que pueden ser motivo de preocupación.

Hay algunos objetos. NET que pueden ser considerado como algo no administrado. Los componentes de la biblioteca de gráficos son un ejemplo.

La mayoría de las "fugas de memoria.NET" no son realmente fugas de memoria en el verdadero sentido. Por lo general, ocurren cuando piensa que ha eliminado un objeto de su uso, pero de hecho el objeto todavía tiene alguna referencia a la aplicación. Un ejemplo común es agregar eventhandlers (obj.SomeEvent+ =omomeevent - or-AddHandler obj.Algún evento, dirección de algún evento) y no eliminarlos.

Estos las' referencias persistentes ' técnicamente no son fugas de memoria, ya que su aplicación todavía las está utilizando técnicamente; sin embargo, si hay suficientes, su aplicación puede sufrir graves impactos en el rendimiento y puede mostrar signos de problemas de recursos (excepciones fuera de memoria, incapaces de obtener controladores de ventana, etc.).

Soy un desarrollador intermedio de.NET y desafortunadamente conozco estos problemas de primera mano. Recomiendo jugar con ANTS Profiler para ayudar a familiarizarse con las referencias persistentes (hay una versión de prueba gratuita) o si desea obtener un poco más de investigación nitty-arenoso usando WinDbg y SOS.DLL para ver el montón administrado. Si usted decide mirar en el último recomiendo leer Tess Ferrandez' blog; ella tiene un montón de grandes tutoriales y consejos sobre el uso de Windbg efectivamente

 21
Author: STW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-21 17:47:25

La respuesta corta sería cualquier cosa que vayas a espaldas del CLR (al sistema operativo) para obtener puede denominarse como ' nativo'.

  • asignación de memoria no administrada. Si 'new' up a chunk of memory in a managed class CantStayManaged, entonces CantStayManaged es responsable de liberar esta memoria (recurso).
  • maneja archivos, canalizaciones, eventos, construcciones de sincronización, etc. - como regla general, si llama a WinAPIs para obtener punteros / manijas a un recurso, entonces esos son "recursos nativos"

Así que ahora CantStayManaged tiene 2 cosas que necesita limpiar antes de que se despida.

  1. Administrado: Campos de miembros y cualquier recurso que el CLR haya asignado. Esto generalmente equivale a llamar a Desechar en sus objetos miembro 'Desechables'.
  2. No administrado: todas las cosas astutas de bajo nivel que tiramos a sus espaldas.

Hay 2 maneras de activar la limpieza de objetos ahora.

  1. Dispose(true) case: Usted llamó a Dispose explícitamente en su tipo. Buen programador.
  2. Dispose(false) case: Se olvidó de llamar Dispose, en cuyo caso el finalizador debería activarse y aún así garantizar una limpieza adecuada.

En ambos casos, los recursos no administrados deben liberarse de las FUGAS de los demás!', 'SE ESTRELLA!"et.toda la superficie. Pero solo debe intentar limpiar los recursos administrados en el caso anterior de Dispose (). En el último caso / finalizador: es posible que el CLR ya haya finalizado y recopilado algunos de sus miembros, por lo que no debe acceder a ellos (CLR no garantiza un orden en el que se finalice un gráfico de objetos.) Por lo tanto, evita problemas al proteger su limpieza administrada con un control de guardia if (AmIBeingCalledFromDispose)

HTH

 1
Author: Gishu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-21 18:10:32