2010-06-30 20 views
7

Quiero saber qué acción se realiza cuando llamamos al método Dispose(). Is Object libera todos los recursos rápidamente en Dispose() call o Dispose() marca que el objeto está listo para la recolección de elementos no utilizados. Y ¿Qué pasó cuando establecemos la referencia de Objeto como NULL? En realidad, tengo la aplicación de formulario de Windows en .NET 2.0. Y quiero llamar al recolector de basura después de que se pasa un cierto tiempo (por ejemplo, después de 5 minutos) para recoger todo el objeto sin referencia.Uso de la recolección de basura?

Respuesta

7

No hay nada de mágico en el método Dispose, es como cualquier otro método. Llamar al método Dispose no realiza ninguna limpieza en el fondo o cambia el estado del objeto, simplemente hace lo que has puesto en el método. Lo especial de esto es que está definido en la interfaz IDisposable, por lo que es la manera estándar de decirle a un objeto que limpie sus recursos.

En el método Dispose, el objeto debe encargarse de todos los recursos no administrados, como las conexiones a la base de datos y los objetos Font.

Cuando libera un objeto, no tiene que preocuparse por ningún recurso administrado. El recolector de basura maneja completamente una estructura como una matriz de bytes, y puede dejarla en el objeto cuando la suelta. No necesita establecer ninguna referencia al null, cuando ya no usa un objeto, el recolector de basura encontrará el mejor momento para eliminarlo y cualquier objeto al que haga referencia.

El recolector de basura normalmente funciona mejor cuando lo deja en paz, no hay necesidad de indicar cuándo debe recoger el objeto no utilizado. Se resolverá por sí solo cuando deba hacerse, y generalmente lo hace mejor que usted, ya que tiene acceso a mucha información sobre el estado de la memoria y el estado de la máquina que su código no tiene.

Puede sentir que debe tratar de mantener el uso de memoria bajo, pero no tiene ninguna ventaja en sí mismo. Una computadora no funciona mejor porque le queda más memoria libre. Por el contrario, si tu código intenta hacer una limpieza, o fuerza al recolector de basura a hacer algo, está haciendo la limpieza cuando debería estar ocupado haciendo algo más importante. El recolector de basura limpiará el objeto no utilizado si es necesario.

+2

Hay una cosa mágica sobre el método Dispose. Se llamará automáticamente a un objeto creado en una declaración 'using'. – tvanfosson

+0

@tvanfosson: Todavía no hay nada de mágico en eso, y es la declaración 'using' que hace algo especialmente dirigido al método Dispose, el método Dispose sigue siendo solo un método ordinario. – Guffa

+0

Me doy cuenta de que el método no difiere en ningún aspecto material de otros métodos, pero diría que es algo mágico que se invoque automáticamente al salir de un bloque en uso. – tvanfosson

-1

El objeto solo está marcado para la recolección de basura, cuando se llama a Dispose(). < - Actualización: esto está mal. Dispose() realmente no hace nada, a menos que usted o el compilador lo invoquen (cuando se usa en una construcción 'using').

De MSDN -

En la mayoría de los casos, el recolector de basura puede determinar el mejor momento para realizar una colección y se debe dejar que se ejecute de forma independiente . Existen situaciones raras cuando una colección forzada puede mejorar el rendimiento de su aplicación . En estos casos, puede inducir la recogida de basuras mediante el método Collect para obligar a un cubo de basura colección

Ver este artículo - http://msdn.microsoft.com/en-us/library/bb384155.aspx

+0

No estoy seguro acerca de su respuesta allí ... –

+2

Esto no es correcto. Dispose se utiliza como una forma de finalización determinística, pero los objetos que no exponen IDisposable aún serán recopilados por el GC. – captaintom

+1

"-1" dio una referencia a la descripción de GC.Collect(). no hay nada como "el objeto solo está marcado para la recolección de basura, cuando se llama Dispose()" – Arseny

-1

Si realmente quiere forzar un uso Recolección de basura:

GC.Collect(); 

favor ver este post por razones de por qué no debe utilizarlo:

What's so wrong about using GC.Collect()?

+0

Pero * ¿debería * forzar una recolección de basura? En casi todos los casos: ¡NO! – dtb

+2

-1 Olvidaste explicar que el código que acabas de darle no debería usarse, y por qué. – Guffa

+0

Pero no lo use a menos que esté realmente seguro de que lo va a ayudar. Los documentos dicen, por ejemplo: "Use el método Collect cuando hay una reducción significativa en la cantidad de memoria que se usa en un punto definido en el código de la aplicación". Lo he usado en un programa que ejecuta 'trabajos' que hacen una gran cantidad de trabajo, para limpiar entre o inmediatamente después de trabajos, lo que ayudó a reducir la huella de memoria cuando el programa no estaba haciendo nada. –

9

Dispose normalmente frees unmanaged resources owned by the object. Llamar al Dispose no desencadena la recolección de basura; su objeto se recoge cuando ya no hay referencias al mismo, lo mismo que si nunca hubiera llamado al Dispose.

Establecer una referencia de objeto a null solo hace que la referencia ya no apunte a ese objeto; normalmente no debería necesitar hacer esto (por ejemplo, casi nunca necesita establecer variables locales en null).

Casi nunca es necesario desencadenar la recolección de basura usted mismo. ¿Está viendo un problema que sugiere que necesita ejecutar la recolección de basura cada 5 minutos, en lugar de hacerlo en el momento en que el tiempo de ejecución lo elija?

+0

OK.Gracias a todos ustedes. Entiendo mucho sobre Dispose() y el recolector de basura. –

0

El punto de recolección automática de basura es que no tiene que preocuparse por la liberación de objetos. No trates de "ayudar" al recolector de basura.

Los objetos se recogen con el tiempo después de que salen del alcance. No hay forma de "liberar" un objeto manualmente o marcarlo para una recolección de basura más rápida. Solo tenga en cuenta qué objetos están dentro del alcance (o referenciados desde objetos en el alcance).

El método Dispose es solo un método. No hace nada relacionado con la recolección de basura. "Desechar" pasa a ser el nombre del método que se llama por la declaración using:

using (var x = expr) { ... } 

es básicamente equivalente a

var x = expr; 
try { ... } finally { x.Dispose(); } 
2

Un objeto es elligible para GC cuando no tiene referencias mantenidos contra eso. Si tiene referencias mantenidas en su contra durante un cierto período de tiempo (administrado por el recolector de basura) comienza a promoverse a través de lo que se conoce como "generaciones".

El método Dispose es simplemente un patrón (no es un mecanismo de eliminación del objeto de lenguaje impuesto) para decir que el objeto ahora puede limpiar cualquier recurso no administrados, cierre de las conexiones etc.

Las acciones realizadas por el Desechar El programador está totalmente controlado por el programador, por lo que usted sabe, podría estar haciendo nada.

El recolector de basura no tiene interés en los métodos Dispose, pero a través del Finalizer, es probable que la lógica Dispose se llame de todos modos, las personas que siguen el patrón IDisposable implementan el finalizador como una última zanja "se olvidó de llamar Dispose así que lo haré justo antes de que el GC me mate "para limpiar los recursos.

Tenga en cuenta que todos los recursos gestionados con el tiempo serán GC'd (a menos que se mantengan referencias) si no se llama a Dispose. Sin embargo, los recursos no administrados solo se recuperarán cuando finalice todo el proceso de la aplicación (así como también cualquier recurso administrado con referencias aún conservadas).

+1

Como un lado, las implementaciones de 'Dispose' frecuentemente incluyen una llamada a 'GC.SuppressFinalize (this);' de modo que la finalización no ocurrirá una segunda vez cuando el objeto es basura recolectada. – Brian

0

Para sus objetos de clase, usted está definiendo qué hará Dispose. Implementa la interfaz IDisposable que contiene el método Dispose y depende de la implementación. Pero generalmente el propósito de Dispose es liberar recursos (gestionados/no gestionados) y hacer que el objeto sea candidato para GC.

En relación con la configuración null podemos decir que es inútil.Simplemente observa que no hay una referencia al objeto de este modo se convierte en candidato para GC, pero una vez más que no hay necesidad de establecer null como GC puede encontrar que no hay referencias al objeto sin que ..

Para las llamadas Collect no se sugiere (hasta que tenga una necesidad extrema y argumentos para eso) como un GC optimizado para saber cuál es el momento adecuado para Collection.

+0

"Pero generalmente Dispose hace que un objeto sea candidato para GC" ... um, no. – captaintom

+0

Dispose no hace que un objeto sea candidato; puede mantener una referencia al objeto para evitar que se recopile. Dispose debería limpiar todos los recursos internos del objeto, si el desarrollador está haciendo su trabajo correctamente. –

+0

Además, en algunos objetos se usa para establecer valores nulos: los objetos con un alcance amplio pueden administrarse en código en lugar de usar el alcance para determinar su recuento de referencia. Establecer null lo hará elegible para GC mucho antes de que salga del alcance. –

0

Disponer, si se implementa correctamente, eliminará todos los recursos administrados que tenga ese dispositivo IDisposable e inmediatamente liberará los recursos no administrados. El objeto en sí se marcará para la recopilación cuando no haya referencias a él. Normalmente, el objeto se utiliza en un bloque using y el método Dispose se llama al final del bloque de forma automática, con el objeto que cae fuera del alcance y es elegible para la recopilación en ese momento.

En el caso general, va a causar más problemas de los que resuelve al interactuar directamente con el recolector de basura. Si cree que debe hacer esto, es más probable que sea una señal de que necesita refactorizar la solución, es decir, tiene demasiado acoplamiento entre las clases, lo que hace que el objeto se mantenga activo más de lo necesario. Una arquitectura más limpia puede dar como resultado una mejor administración de la vida útil del objeto por parte del sistema.

Consulte MSDN para una discusión sobre cómo implement the IDisposable pattern.

1

Otras personas aquí han respondido suficientemente al "cómo interactúa IDisposable con el recolector de basura" y "cuándo debo llamar al GC.Collect" partes de la pregunta.

Tengo una publicación de blog que detalla acerca de when you should set variables to null to help the garbage collector (la tercera parte de la pregunta). La respuesta corta es "casi nunca, a menos que sea una variable estática".

Cuestiones relacionadas