¿Qué son exactamente los recursos no administrados?


Respuestas:


177

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) liberará esa memoria por usted.

Los recursos no administrados son todo lo que el recolector de basura no sabe. Por ejemplo:

  • Abrir archivos
  • Conexiones de red abiertas
  • Memoria no administrada
  • En XNA: búferes 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, llama Disposea ese objeto o (en C #) usa la usinginstrucción que se encargará de llamar Disposepor ti.

Si descuida Disposesus recursos no administrados correctamente, el recolector de basura eventualmente lo manejará por usted cuando el objeto que contiene ese recurso es recolección de basura (esto es "finalización"). Pero debido a que el recolector de basura no sabe acerca de los recursos no administrados, no puede determinar cuán mal necesita liberarlos, por lo que es posible que su programa funcione mal o se quede sin recursos por completo.

Si implementa una clase sí mismo que las manijas no administrado los recursos, es a usted para poner en práctica Disposey Finalizecorrectamente.


77
¿En qué categoría se encuentra la conexión de base de datos abierta? Gestionado / No gestionado?
Deviprasad Das

8
+1 Otras respuestas pierden el punto importante al que llama Descartar en un objeto administrado que maneja internamente la liberación del recurso no administrado que envuelve (por ejemplo, identificador de archivo, GDI + mapa de bits, ...) y que si accede directamente a recursos no administrados ( PInvocar, etc.) necesita manejar eso.
Ian Mercer

2
@Dev: no administrado, ya que el GC no lo sabe (suponiendo que no esté utilizando alguna base de datos hipotética en memoria administrada). Pero el objeto de conexión en sí mismo podría no contener un recurso no administrado. Presumiblemente, la conexión de la base de datos utiliza un archivo abierto o una conexión de red en algún lugar , pero es posible que otro objeto (que no sea el objeto de conexión) esté manejando ese recurso no administrado (tal vez la biblioteca de la base de datos almacena en caché las conexiones). Consulte la documentación y vea dónde le pide que llame Disposeo use using.
Andrew Russell

11
Tengo un comentario / pregunta básica sobre esto, ¿puedo relacionar un objeto como administrado / no administrado solo por el tipo, por ejemplo, la cadena está administrada, DataSet no está administrado (por lo que tiene un método Dispose ()) , Las conexiones de la base de datos no están administradas (porque tienen disposición), etc. Entonces, ¿se supone que si tiene un método "Dispose ()", entonces no está administrado? Además de eso, ¿cuál sería un objeto XmlDocument? Gracias
gaders

15
@ganders Esa es una buena regla general. Aunque tenga en cuenta que todas las instancias de clase C # son objetos administrados. Si una instancia de una clase pudiera contener recursos no administrados, entonces esa clase debería implementarse IDisposable. Si una clase se implementa IDisposable, debe deshacerse de las instancias de esa clase con usingo Dispose()cuando haya terminado con ellas. En base a esto, su conversación reversa: si una clase se implementa IDisposable, entonces probablemente retenga recursos no administrados internamente.
Andrew Russell

56

Algunos usuarios clasifican los archivos abiertos, las conexiones db, la memoria asignada, los mapas de bits, las secuencias de archivos, etc. entre los recursos administrados, otros entre los no administrados. Entonces, ¿son administrados o no administrados?

Mi opinión es que la respuesta es más compleja: cuando abre un archivo en .NET, probablemente use algún tipo de .NET incorporado System.IO.File, FileStream u otra cosa. Debido a que es una clase .NET normal, se administra. Pero es un contenedor, que en su interior hace el "trabajo sucio" (se comunica con el sistema operativo mediante Win32 dlls, llama a funciones de bajo nivel o incluso instrucciones de ensamblador) que realmente abren el archivo. Y esto es, lo que .NET no sabe, no administrado. Pero quizás pueda abrir el archivo usted mismo utilizando las instrucciones del ensamblador y omitir las funciones del archivo .NET. Entonces el identificador y el archivo abierto son recursos no administrados.

Lo mismo con la base de datos: si usa algún ensamblaje de base de datos, tiene clases como DbConnection, etc., las conoce .NET y las administra. Pero envuelven el "trabajo sucio", que no está administrado (asignar memoria en el servidor, establecer conexión con él, ...). Si no utiliza esta clase de contenedor y abre algún socket de red usted mismo y se comunica con su propia base de datos extraña usando algunos comandos, no se administra.

Estas clases de contenedor (File, DbConnection, etc.) se administran, pero en su interior utilizan recursos no administrados de la misma manera que usted, si no utiliza los contenedores y hace el "trabajo sucio" por sí mismo. Y por lo tanto, estos envoltorios implementan patrones de disposición / finalización. Es su responsabilidad permitir que el programador libere recursos no administrados cuando ya no se necesita el contenedor, y liberarlos cuando el contenedor es basura recolectada. El contenedor será recolectado correctamente por el recolector de basura, pero los recursos no administrados en el interior se recolectarán utilizando el patrón Dispose / Finalize.

Si no utiliza clases de contenedor integradas de .NET o de terceros y abre archivos según algunas instrucciones de ensamblador, etc. en su clase, estos archivos abiertos no se administran y DEBE implementar el patrón de disposición / finalización. Si no lo hace, habrá 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 su aplicación finalice.

Pero su responsabilidad también es cuando usa estos envoltorios. Para aquellos que implementan desechar / finalizar (usted los reconoce, que implementan IDisposable), implemente también su patrón de disposición / finalización y deseche incluso estos contenedores o déles la señal para liberar sus recursos no administrados. Si no lo hace, los recursos se liberarán después de un tiempo indefinido, pero está limpio liberarlo de inmediato (cierre el archivo inmediatamente y no lo deje abierto y bloqueado durante varios minutos / horas al azar). Entonces, en el método Dispose de su clase, llama a los métodos Dispose de todos sus contenedores usados.


1
Buena en la claridad adicional enunmanaged vs managed resources
ahora el que no debe ser nombrado.

Gracias por tu respuesta. ¿En qué clases se recomienda que llamemos a Dispose?
BKSpurgeon

2
Esto es simple. En cada clase que utilice, debe verificar si implementa una interfaz IDisposable. En caso afirmativo, si usa dicha clase en un método (por ejemplo: abrir un archivo, almacenar texto, cerrar el archivo), puede usarlo usando el patrón () {}, que llama a Eliminar automáticamente. Si usa dicha clase en más métodos (por ejemplo: su clase contiene Archivo, en el constructor abre el archivo, luego varios métodos agregan algunos registros ...), entonces debe implementar la interfaz IDisposable por su clase, implementar el patrón Dispose / Finalize y disponer adecuadamente el objeto de esa clase.
Martas

1
"... alguna clase .NET incorporada System.IO.File, FileStream u otra cosa. Debido a que es una clase .NET normal, se administra". Con respeto, esto es incorrecto y engañoso. No se gestionan . Si se administraron, entonces podría asignar estas clases y esperar que el recolector de basura maneje completamente la desasignación de todos los recursos de una manera determinista. Sin embargo, esto llevará a que los identificadores de archivos y los recursos no administrados se bloqueen y retengan por mucho más tiempo del necesario porque el recolector de basura no desasignará la clase y no la finalizará por un tiempo potencialmente largo.
AaronLS

1
@AaronLS en su comentario habló de "FileStream" al referirlo como no administrado pero no lo es, aunque internamente utiliza recursos no administrados para hacer su trabajo. En el mundo administrado, Microsoft le ha ocultado muchas cosas no administradas al implementar el disponer de patrón. El código administrado no significa que no utiliza recursos no administrados. Sin embargo, Microsoft ha hecho un buen trabajo al implementar IDisposable en ese tipo de objetos. Esto se evidencia por el hecho de que implementa IDisposable. Con respecto a esa evidencia, deberíamos considerarla un objeto administrado.
Malik Khalil

12

Los recursos no administrados son aquellos que se ejecutan fuera del tiempo de ejecución de .NET (CLR) (también conocido como código que no es .NET). Por ejemplo, una llamada a un archivo DLL en la API de Win32 o una llamada a un archivo .dll escrito en C ++.


6

Un "recurso no administrado" 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 por 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 tipo único 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 indica que realice toda la limpieza de la que es responsable.

En algunos casos, los objetos tendrán en cuenta la posibilidad de que puedan abandonarse sin que nadie haya llamado a Dispose primero. El GC permite que los objetos soliciten 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.

Desafortunadamente, términos como "recurso administrado" y "recurso no administrado" son 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 ocupará si se llama a Dispose, o tener una responsabilidad de limpieza que se debe resolver a través de Dispose, pero que puede También se encargará de Finalizar.


5

La diferencia básica entre un recurso administrado y un recurso no administrado es que el recolector de basura conoce todos los recursos administrados, en algún momento el GC aparecerá y limpiará toda la memoria y los recursos asociados con un objeto administrado. El GC no conoce los recursos no administrados, como los archivos, la secuencia y los identificadores, por lo que si no los limpia explícitamente en su código, terminará con pérdidas de memoria y recursos bloqueados.

Robado de aquí , no dudes en leer la publicación completa.


2

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érfano. Cualquier otra cosa no está gestionada. Por ejemplo, la interacción con COM puede crear objetos en el espacio de memoria de proceso, pero CLR no se ocupará de ello. En este caso, el objeto gestionado que realiza llamadas a través de la frontera gestionada debe ser el responsable de cualquier cosa más allá de él.


0

Primero, comprendamos cómo solían ejecutarse los programas VB6 o C ++ (aplicaciones no Dotnet). Sabemos que las computadoras solo entienden el código de nivel de máquina. El código de nivel de máquina también se llama como 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 ejecutarlo en otro sistema operativo, fallará. Entonces, el problema con este estilo de ejecución de programa es que no es portátil de una plataforma a otra.

Ahora comprendamos cómo se ejecuta un programa .Net. Usando dotnet podemos crear diferentes tipos de aplicaciones. Algunos de los tipos comunes de aplicaciones .NET incluyen aplicaciones web, Windows, de consola y móviles. Independientemente del tipo de aplicación, cuando ejecuta cualquier aplicación .NET sucede lo siguiente

  1. La aplicación .NET se compila en lenguaje intermedio (IL). IL también se conoce como lenguaje intermedio común (CIL) y lenguaje intermedio de Microsoft (MSIL). Las aplicaciones .NET y no .NET generan un ensamblado. Los ensamblados tienen una extensión de .DLL o .EXE. Por ejemplo, si compila una aplicación de consola o Windows, obtiene un .EXE, donde, como cuando compilamos un proyecto de biblioteca web o de clase, obtenemos un .DLL. La diferencia entre un ensamblado .NET y NON .NET es que, el ensamblaje DOTNET está en formato de lenguaje intermedio, mientras que el ensamblaje NON DOTNET está en formato de código nativo.

  2. 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 entender.

Entonces, en .NET, la ejecución de la aplicación consta de 2 pasos: 1. Compilador de lenguaje, compila el código fuente en lenguaje intermedio (IL) 2. El compilador JIT en CLR convierte, el IL en código nativo que luego puede ejecutarse en el sistema operativo subyacente .

Dado que un ensamblado .NET está en formato de lenguaje Intermedaite y no en código nativo, los ensamblados .NET son portátiles a cualquier plataforma, siempre que la plataforma de destino tenga Common Language Runtime (CLR). El CLR de la plataforma de destino convierte el lenguaje Intermedaite en código nativo que el sistema operativo subyacente puede entender. Languge intermedio también se llama como 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 desasignar la memoria consumida por un objeto. Si un programador se olvida de desasignar memoria, podemos encontrarnos con excepciones difíciles de detectar. Por otro lado, un programador .NET no necesita preocuparse por desasignar la memoria consumida por un objeto. CLR proporciona la administración automática de memoria, también conocida como recolección de basura. Aparte, de la recolección de basura, hay varios otros beneficios provistos por el CLR, que discutiremos en una sesión posterior. Dado que CLR administra y ejecuta el lenguaje intermedio, también se lo llama (IL) como 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 lugar, después de cerrar el programa, el código nativo se desecha 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), mientras que en .NET tenemos lenguaje intermedio y CLR (Common Language Runtime)

Esto se proporciona desde este enlace: es un gran tutor. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.