2010-08-13 17 views
29

tuve algunos consejos que suena muy mal recientemente de un "alto" desarrollador/compañero de trabajo en relación con el recolector de basura de C# como ...¿Cuáles son las diferencias fundamentales entre la recolección de basura en C# y Java?

  • "Es necesario utilizar destructores todas partes en C# porque el recolector de basura no se puede confiar en eso ".

  • "El recolector de basura C# no puede ser pensado como el recolector de Java ".

Esto suena muy sospechoso para mí, por lo que yo sé las diferencias entre el C# y recolectores de basura de Java son los siguientes ...

  • El C# es un generacional basura colector, Java es marca concurrente barrer en 1.6 con G1 como el nuevo colector de basura predeterminado (generacional) con Java 7 y como opcional desde ~ 1.6.21. Hasta ahora como sé
  • C# como un lenguaje tiene la capacidad de disponer manualmente de los objetos que implementar IDisposable. Java debe utilizar siempre la recolección de elementos no utilizados, aunque algunos marcos como SWT requieren que invoque manualmente los métodos a la memoria de liberación en el código nativo subyacente .

que se dan cuenta de que Java y C# son sólo los idiomas y los recolectores de basura son un componente de tiempo de ejecución, sin embargo, para este caso estoy hablando específicamente sobre el Sol/Oracle JVM y Microsoft .NET Runtime.

¿Alguien tiene comentarios?

+5

Su compañero de trabajo está completamente equivocado sobre los destructores. Citando las Pautas de diseño de marco de Microsoft: "Realmente no desea escribir un finalizador si puede evitarlo". – TrueWill

+5

Me temo que su compañero de trabajo está muy equivocado. Un finalizador ni siquiera es realmente un destructor, no es una forma de desasignar manualmente una instancia de objeto gestionado. De hecho, si tiene un finalizador, es llamado por el recolector de basura. Existen finalizadores para que pueda limpiar la memoria no administrada, como si hiciera una llamada de WinAPI y obtuviera un control. El GC no puede recolectar la memoria no administrada como manejadores, podría usar un finalizador para eso (aunque con .Net 2.0 y arriba, probablemente irías con un SafeHandle en su lugar). – JMarsch

+2

Tengo que estar en desacuerdo sobre que GC no sea confiable. Hemos estado desarrollando con .Net desde 2001, incluidas aplicaciones web y algunos servicios de Windows (los servicios de Windows pueden ejecutarse durante meses y, por lo general, solo se reinician cuando una Actualización de Windows requiere un reinicio). las únicas "filtraciones" que he visto caen en 2 cubos: la mayoría de los casos donde guardamos una referencia (un error en nuestro código) y algunos casos en que nuestro código llamaba a código no administrado (antiguo C++ DLL o Winapi, etc.), y hubo una fuga en el código no administrado (el GC no puede ayudarlo con la memoria no administrada) – JMarsch

Respuesta

15

El consejo que le han dado es, en términos generales, un montón de tonterías.

Tanto C# como Java tienen GC que intentan optimizar la recuperación rápida de muchos objetos pequeños. Están diseñados para resolver el mismo problema, lo hacen de maneras ligeramente diferentes, pero como usuario las diferencias técnicas en su enfoque para usarlas son mínimas, incluso inexistentes para la mayoría de los usuarios.

IDisposable no tiene nada que ver con el GC como tal. Es una forma estándar de denominar a los métodos que de lo contrario se llamarían close, destroy, dispose, etc., y a menudo se los denomina así en Java. Existe una propuesta para que Java 7 agregue algo muy similar a la palabra clave using que llamaría a un método similar close.

"Destructors" en C# hace referencia a los finalizadores; esto se hizo deliberadamente para confundir a los programadores de C++. :) La especificación de CLR los llama finalizadores, exactamente como lo hace la JVM.

Hay muchas maneras en que Java y C#/CLR difieren (tipos de valor de usuario, propiedades, genéricos y toda la familia de características relacionadas conocidas como Linq), pero el GC es un área donde puede desarrollar una cantidad sustancial de software antes de que deba preocuparse mucho por la diferencia entre ellos.

+2

Gracias por señalar 'IDisposable' no tiene nada que ver con una recolección de basura. Esa es una idea errónea muy común. –

+2

¡Oh, háblame de eso! He pasado horas en este sitio tratando de explicar que no * todo * que implemente las necesidades de 'IDisposable' también debe tener un finalizador. p.ej. cualquier cosa que simplemente agregue otros 'IDisposables'. O los objetos generados por los métodos 'yield return '. O cualquier cosa con un destructor en C++/CLI. O cualquier clase que no quiere manejar llamadas de un hilo aleatorio.El documento de MSDN agrava este malentendido de muchas maneras. –

3

Está al revés en los destructores. Necesita no usar destructores en C# a menos que sea vital. Y si los usa, debe llamar a SuprimirFinalizar() si sabe que el objeto se encuentra en un estado donde el código del destructor ya no es necesario (la mayoría de las veces porque la misma limpieza se produjo en una llamada a IDisposable.Dispose(). Si un objeto tiene un destructor y SuppressFinalize no se ha llamado, vivirá más tiempo (para que pueda tener ese destructor llamado).

El recolector de basura sin duda puede confiarse. No se puede confiar en que llame a un destructor, o para hacerlo dentro de una cierta cantidad de tiempo, pero eso no es una cuestión de que no sea confiable, es una cuestión de que sea confiable en la recolección de basura, que es su trabajo!

No lo sé tanto sobre el recolector de basura de Java, y no tengo dudas de que tiene razón al decir que no se pueden pensar de como el uno al otro cuando se está llegando a los detalles más finos, aunque espero por el bien de los programadores de Java que se pueda pensar como el de .NET la mayor parte del tiempo, que es no pensar en absoluto , generalmente no es necesario.

2

Me temo que su compañero de trabajo es incorrecto, pero no crea en mi palabra. Vamos a tener un enlace fest!

Éstos son algunos buenos artículos sobre GC: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Además, el weblog de Maoni tiene algunas grandes cosas (le llevará hasta la fecha, así, ya que los artículos arriba son bastante viejo): http://blogs.msdn.com/b/maoni/

Además, esta misma semana, Raymond Chen está haciendo una serie de GC: http://blogs.msdn.com/b/oldnewthing/archive/2010/08/13/10049634.aspx

Aquí hay una buena discusión sobre el uso de botar y Fina lization: http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx

+1

Sería útil obtener pequeños resúmenes de los puntos que se destacan para apoyar su declaración, para cada enlace. –

Cuestiones relacionadas