c# - pattern - ¿Qué son exactamente los recursos no administrados?
object no contiene una definicion para dispose (7)
Algunos usuarios clasifican los archivos abiertos, las conexiones de base de datos, la memoria asignada, los mapas de bits, las secuencias de archivos, etc. entre los recursos administrados, y otros entre los no administrados. Entonces, ¿están administrados o no?
Mi opinión es que la respuesta es más compleja: cuando abre un archivo en .NET, probablemente use alguna clase .NET incorporada System.IO.File, FileStream u otra cosa. Debido a que es una clase .NET normal, se administra. Pero es un contenedor, que dentro hace el "trabajo sucio" (se comunica con el sistema operativo usando Win32 dlls, llamando a funciones de bajo nivel o incluso instrucciones de ensamblador) que realmente abre el archivo. Y esto es, lo que .NET no conoce, no administrado. Pero quizás pueda abrir el archivo usted mismo usando las instrucciones del ensamblador y eludir las funciones de archivos .NET. Entonces, el identificador y el archivo abierto son recursos no administrados.
Lo mismo con el DB: si usa algún ensamblado de base de datos, tiene clases como DbConnection, etc., que son conocidas por .NET y administradas. Pero envuelven el "trabajo sucio", que no está administrado (asigna memoria en el servidor, establece conexión con él, ...). Si no usa esta clase de contenedor y abre un socket de red usted mismo y se comunica con su propia base de datos extraña usando algunos comandos, no se administra.
Estas clases contenedoras (File, DbConnection, etc.) se administran, pero dentro utilizan recursos no administrados de la misma manera que usted, si no usa los contenedores y hace el "trabajo sucio" usted mismo. Y, por lo tanto, estas envolturas implementan los patrones Dispose / Finalize. Es su responsabilidad permitir que el programador libere recursos no administrados cuando el contenedor ya no es necesario, y liberarlos cuando el contenedor es basura. El recopilador de basura recogerá correctamente el contenedor, pero los recursos no administrados que se encuentran en el interior se recopilarán utilizando el patrón Dispose / Finalize.
Si no utiliza las clases .NET integradas o de envoltura de terceros y abre archivos con algunas instrucciones de ensamblador, etc. en su clase, estos archivos abiertos no se administran y DEBE implementar el patrón de eliminación / finalización. Si no lo hace, habrá una pérdida de memoria, recurso bloqueado para siempre, etc. incluso cuando ya no lo use (operación de archivo completa) o incluso después de que finalice la aplicación.
Pero su responsabilidad también es cuando usa estas envolturas. Para aquellos que implementan dispose / finalize (los reconoce, que implementan IDisposable), implemente también su patrón de eliminación / finalización y deseche incluso estos wrappers o déles la señal para liberar sus recursos no administrados. Si no lo hace, los recursos estarán disponibles después de un tiempo indefinido, pero está limpio liberarlo inmediatamente (cierre el archivo inmediatamente y no lo deje abierto y bloqueado aleatoriamente por varios minutos / horas). Entonces, en el método Dispose de su clase, llama a Dispose methods de todos sus wrappers usados.
Quiero saber sobre los recursos no administrados. ¿Alguien puede darme una idea básica?
Cualquier recurso para el que se asigna memoria en el montón administrado .NET es un recurso administrado. CLR es completamente consciente de este tipo de memoria y hará todo lo posible para asegurarse de que no quede huérfana. Cualquier otra cosa no está administrada. Por ejemplo, interoperar con COM, podría crear objetos en el espacio de la memoria proces, pero CLR no se encargaría de ello. En este caso, el objeto gestionado que realiza llamadas a través de la delimitación gestionada debe ser el responsable de todo lo que esté más allá.
La diferencia básica entre un recurso administrado y no administrado es que el recolector de basura conoce todos los recursos administrados, en algún punto en el tiempo el GC vendrá y limpiará toda la memoria y los recursos asociados con un objeto administrado. El GC no tiene conocimiento de recursos no administrados, como archivos, rutas y controladores, por lo que si no los limpia de forma explícita en el código, terminará con pérdidas de memoria y recursos bloqueados.
Robado desde here , no dudes en leer la publicación completa.
Los recursos administrados básicamente significan "memoria administrada" que es administrada por el recolector de basura. Cuando ya no tenga ninguna referencia a un objeto administrado (que usa memoria administrada), el recolector de basura (eventualmente) lanzará esa memoria por usted.
Los recursos no administrados son todo lo que el recolector de basura no conoce. Por ejemplo:
- Abrir archivos
- Conexiones de red abiertas
- Memoria no administrada
- En XNA: buffers de vértices, búferes de índice, texturas, etc.
Normalmente desea liberar esos recursos no administrados antes de perder todas las referencias que tiene al objeto que los administra. Para ello, llame a Dispose
sobre ese objeto, o (en C #) usando la instrucción using
que manejará la invocación de Dispose
para usted.
Si descuida Dispose
de sus recursos no administrados correctamente, el recolector de basura finalmente lo manejará cuando el objeto que contiene ese recurso sea basura (esto es "finalización"). Pero debido a que el recolector de basura no sabe acerca de los recursos no administrados, no puede decir cuánto necesita liberarlos, por lo que es posible que su programa funcione mal o se quede sin recursos por completo.
Si implementa una clase usted mismo que maneja recursos no administrados, depende de usted implementar Dispose
y Finalize
correctamente.
Los recursos no administrados son aquellos que se ejecutan fuera del tiempo de ejecución .NET (CLR) (también conocido como código no .NET). Por ejemplo, una llamada a un archivo DLL en la API de Win32 o una llamada a un archivo .dll escrito en C ++.
Primero, comprendamos cómo se ejecutan los programas VB6 o C ++ (aplicaciones sin Dotnet). Sabemos que las computadoras solo entienden el código de nivel de la máquina. El código de nivel de máquina también se denomina código nativo o binario. Entonces, cuando ejecutamos un programa VB6 o C ++, el compilador de idioma respectivo, compila el código fuente del idioma respectivo en código nativo, que luego puede ser entendido por el sistema operativo subyacente y el hardware.
El código nativo (código no administrado) es específico (nativo) del sistema operativo en el que se genera. Si toma este código nativo compilado e intenta ejecutar en otro sistema operativo, fallará. Entonces, el problema con este estilo de ejecución de programa es que no es portátil desde una plataforma a otra.
Permítanos ahora entender cómo se ejecuta un programa .Net. Usando dotnet podemos crear diferentes tipos de aplicaciones. Algunos de los tipos más comunes de aplicaciones .NET incluyen Web, Windows, Consola y Aplicaciones Móviles. Independientemente del tipo de aplicación, cuando ejecuta cualquier aplicación .NET ocurre lo siguiente
La aplicación .NET se compila en el lenguaje intermedio (IL). IL también se conoce como Lenguaje Intermedio Común (CIL) y lenguaje Intermedio de Microsoft (MSIL). Ambas aplicaciones .NET y no .NET generan un ensamblaje. Los ensambles tienen una extensión de .DLL o .EXE. Por ejemplo, si compilas una aplicación de Windows o Consola, obtienes un .EXE, mientras que cuando compilamos un proyecto de biblioteca web o Clase obtenemos un .DLL. La diferencia entre un ensamblado .NET y NON .NET es que DOTNET Assembly está en formato de lenguaje intermedio donde el ensamblaje NON DOTNET está en formato de código nativo.
Las aplicaciones NO DOTNET pueden ejecutarse directamente sobre el sistema operativo, mientras que las aplicaciones DOTNET se ejecutan sobre un entorno virtual llamado Common Language Runtime (CLR). CLR contiene un componente llamado Just In-Time Compiler (JIT), que convertirá el lenguaje intermedio en código nativo que el sistema operativo subyacente puede comprender.
Entonces, en .NET, la ejecución de la aplicación consta de 2 pasos 1. El compilador de lenguaje compila el código fuente en el lenguaje intermedio (IL) 2. El compilador JIT en CLR convierte el IL en código nativo que luego se puede ejecutar en el sistema operativo subyacente. .
Dado que un ensamblado .NET está en formato Intermedaite Language y no en código nativo, los ensamblados .NET son portátiles para cualquier plataforma, siempre que la plataforma objetivo tenga Common Language Runtime (CLR). El CLR de la plataforma objetivo convierte el Idioma Intermedaite en un código nativo que el sistema operativo subyacente puede comprender. Languge Intermedio también se llama código administrado. Esto se debe a que CLR administra el código que se ejecuta dentro de él. Por ejemplo, en un programa VB6, el desarrollador es responsable de la desasignación de la memoria consumida por un objeto. Si un programador olvida desasignar la memoria, podemos encontrar excepciones difíciles de detectar. Por otro lado, un programador de .NET no necesita preocuparse por la desasignación de la memoria consumida por un objeto. La administración automática de memoria, también conocida como colección de grabación, es proporcionada por CLR. Además, de la recolección de basura, hay otros beneficios proporcionados por el CLR, que discutiremos en una sesión posterior. Como CLR está administrando y ejecutando el Lenguaje Intermedio, este (IL) también se llama código administrado.
.NET admite diferentes lenguajes de programación como C #, VB, J # y C ++. C #, VB y J # solo pueden generar código administrado (IL), mientras que C ++ puede generar tanto código administrado (IL) como código no administrado (código nativo).
El código nativo no se almacena permanentemente en ningún lado, después de que cerramos el programa, el código nativo se descartaaa. Cuando ejecutamos el programa nuevamente, el código nativo se genera nuevamente.
El programa .NET es similar a la ejecución del programa Java. En java tenemos códigos de bytes y JVM (Java Virtual Machine), donde como en .NET tenemos el lenguaje intermedio y CLR (Common Language Runtime)
Esto se proporciona a partir de este enlace: es un gran tutor. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html
Un "recurso no gestionado" no es una cosa, sino una responsabilidad. Si un objeto posee un recurso no administrado, eso significa que (1) alguna entidad externa ha sido manipulada de una manera que puede causar problemas si no se limpia, y (2) el objeto tiene la información necesaria para realizar dicha limpieza y es responsable para hacerlo
Aunque muchos tipos de recursos no administrados están muy fuertemente asociados con varios tipos de entidades del sistema operativo (archivos, identificadores GDI, bloques de memoria asignados, etc.), no existe un solo tipo de entidad que todos compartan aparte de la responsabilidad de limpiar. Por lo general, si un objeto tiene la responsabilidad de realizar la limpieza, tendrá un método de eliminación que le ordena llevar a cabo toda la limpieza de la que es responsable.
En algunos casos, los objetos tendrán en cuenta la posibilidad de que puedan ser abandonados sin que nadie haya llamado primero Dispose. El GC permite que los objetos soliciten la notificación de que han sido abandonados (llamando a una rutina llamada Finalizar), y los objetos pueden usar esta notificación para realizar la limpieza ellos mismos.
Los términos como "recurso administrado" y "recurso no administrado" son, desafortunadamente, utilizados por diferentes personas para significar cosas diferentes; francamente, creo que es más útil pensar en términos de objetos como no tener ninguna responsabilidad de limpieza, tener una responsabilidad de limpieza que solo se atenderá si se llama a Dispose o tener una responsabilidad de limpieza que se debe cuidar mediante Dispose, pero que puede también ser atendido por Finalize.