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
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.
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
No estoy seguro acerca de su respuesta allí ... –
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" 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
Si realmente quiere forzar un uso Recolección de basura:
GC.Collect();
favor ver este post por razones de por qué no debe utilizarlo:
Pero * ¿debería * forzar una recolección de basura? En casi todos los casos: ¡NO! – dtb
-1 Olvidaste explicar que el código que acabas de darle no debería usarse, y por qué. – Guffa
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. –
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?
OK.Gracias a todos ustedes. Entiendo mucho sobre Dispose() y el recolector de basura. –
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(); }
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).
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
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
.
"Pero generalmente Dispose hace que un objeto sea candidato para GC" ... um, no. – captaintom
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. –
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. –
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.
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".
- 1. Recolección de basura
- 2. y recolección de basura
- 3. ¿Deberíamos utilizar la recolección de basura "estación de trabajo" o la recolección de basura "servidor"?
- 4. Retraso de recolección de basura?
- 5. ¿Notificación de recolección de basura?
- 6. recolección de basura de java
- 7. Supresión de la recolección de basura C#
- 8. JVM sin recolección de basura
- 9. multiprocesamiento y recolección de basura
- 10. ¿WinRT tiene recolección de basura?
- 11. Recolección de basura en Delphi
- 12. Cómo depurar la Recolección de basura .net?
- 13. ¿NewLISP usa la recolección de basura?
- 14. referencia interna impide la recolección de basura
- 15. extremadamente largos tiempos de recolección de basura
- 16. Recolección de basura vs. punteros compartidos
- 17. Herramienta de recolección de basura para dalvik
- 18. Node.js y V8 de recolección de basura
- 19. Patrones inusuales de recolección de basura
- 20. Fuga de memoria con la recolección de basura de Cocoa
- 21. ¿Trabajador de fondo y recolección de basura?
- 22. Java no recolección de basura memoria
- 23. Recolección de basura en hilos Perl
- 24. Recolección de basura de los miembros estáticos
- 25. Recolección de basura de campos privados
- 26. variable = SET NULL para la recolección de basura
- 27. ¿Obtiene la recolección de basura Objective-C 2.0 estructuras C?
- 28. ¿Qué desencadena una recolección de basura gen2?
- 29. Recolección de basura, ¿debemos confiar en ella?
- 30. .NET Recolección de basura e hilos nativos
Hay una cosa mágica sobre el método Dispose. Se llamará automáticamente a un objeto creado en una declaración 'using'. – tvanfosson
@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
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