Aquí podría ser tu PUBLICIDAD


Establecer objetos en Null / Nothing después de su uso en .NET

votos
173

¿Debería configurar todos los objetos null( Nothingen VB.NET) una vez que haya terminado con ellos?

Entiendo que en .NET es esencial disponer de instancias de objetos que implementen la IDisposableinterfaz para liberar algunos recursos, aunque el objeto aún puede ser algo después de su eliminación (de ahí la isDisposedpropiedad en formularios), así que supongo que aún puede residir. en memoria o al menos en parte?

También sé que cuando un objeto se sale del alcance, se marca para que esté listo para el próximo pase del recolector de basura (aunque esto puede llevar tiempo).

Entonces, con esto en mente, ¿lo configurará para nullacelerar el sistema liberando la memoria, ya que no tiene que resolverse que ya no está en el alcance y son malos efectos secundarios?

Los artículos de MSDN nunca hacen esto en ejemplos y actualmente lo hago porque no puedo ver el daño. Sin embargo, he encontrado una mezcla de opiniones, por lo que cualquier comentario es útil.

Publicado el 05/08/2008 a las 21:14
fuente por usuario John
En otros idiomas...        العربية       

13 respuestas

votos
66

Karl tiene toda la razón, no hay necesidad de establecer objetos para nulos después del uso. Si un objeto se implementa IDisposable, simplemente asegúrate de llamar IDisposable.Dispose()cuando hayas terminado con ese objeto (envuelto en un try... finallyo un using()bloque). Pero incluso si no recuerda llamar Dispose(), el método del finalizador en el objeto debería estar llamando Dispose()por usted.

Pensé que este era un buen tratamiento:

Buscando en IDisposable

y esto

Comprensión IDisposable

No tiene sentido intentar adivinar el GC y sus estrategias de gestión porque es autoajustable y opaco. Hubo una buena discusión sobre el funcionamiento interno con Jeffrey Richter en Dot Net Rocks aquí: Jeffrey Richter en el Windows Memory Model y el libro de Richters CLR a través de C # capítulo 20 tiene un gran tratamiento:

Respondida el 05/08/2008 a las 09:56
fuente por usuario Kev


Aquí podría ser tu PUBLICIDAD


votos
33

Otra razón para evitar el establecimiento de objetos a nulo cuando haya terminado con ellos es que realmente puede mantenerlos vivos durante más tiempo.

p.ej

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

permitirá que el objeto referido por someType sea GC'd después de la llamada a "DoSomething" pero

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is NOT eligible for garbage collection yet
    // because that variable is used at the end of the method         

    // ... rest of method not using 'someType' ...
    someType = null;
}

a veces puede mantener el objeto vivo hasta el final del método. El JIT generalmente optimiza la asignación a nulo , por lo que ambos bits de código terminan siendo el mismo.

Respondida el 15/08/2008 a las 03:43
fuente por usuario Wilka

votos
15

No, no anules objetos. Puede consultar http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx para obtener más información, pero configurar las cosas anular no hará nada, excepto ensuciar su código.

Respondida el 05/08/2008 a las 09:23
fuente por usuario Karl Seguin

votos
7

En general, no hay necesidad de anular objetos después de su uso, pero en algunos casos creo que es una buena práctica.

Si un objeto implementa IDisposable y se almacena en un campo, creo que es bueno anularlo, solo para evitar el uso del objeto eliminado. Los errores del siguiente tipo pueden ser dolorosos:

this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();

Es bueno anular el campo después de tirarlo, y obtener un NullPtrEx justo en la línea donde el campo se usa nuevamente. De lo contrario, podría encontrarse con algún error críptico en la línea (dependiendo de lo que DoSomething haga).

Respondida el 09/08/2008 a las 12:16
fuente por usuario dbkk

votos
7

También:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
Respondida el 05/08/2008 a las 09:37
fuente por usuario Steve Tranby

votos
6

Lo más probable es que su código no esté lo suficientemente estructurado si siente la necesidad de nullvariables.

Hay varias formas de limitar el alcance de una variable:

Como lo mencionó Steve Tranby

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

Del mismo modo, puede simplemente usar corchetes:

{
    // Declare the variable and use it
    SomeObject object = new SomeObject()
}
// The variable is no longer available

Encuentro que usar corchetes sin ningún "encabezado" para realmente limpiar el código y ayudar a que sea más comprensible.

Respondida el 09/08/2008 a las 01:13
fuente por usuario mbillard

votos
5

En general, ninguna necesidad de fijar a nulo. Pero supongamos que tiene una funcionalidad de reinicio en su clase.

Entonces es posible hacer, ya que no desea llamar disponer dos veces, ya que algunos de los Desechar no puede implementarse correctamente y lanzar una excepción System.ObjectDisposed.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
Respondida el 17/04/2012 a las 09:55
fuente por usuario Munish Goyal

votos
4

La única vez que debe establecer que una variable sea nula es cuando la variable no se salga del alcance y ya no necesite los datos asociados con ella. De lo contrario, no hay necesidad.

Respondida el 05/08/2008 a las 09:32
fuente por usuario Bob

votos
3

este tipo de "no hay necesidad de ajustar los objetos a cero después de su uso" no es del todo exacta. Hay momentos en que necesita para anular la variable después desecharlo.

Sí, debe llamar SIEMPRE .Dispose()o .Close()en cualquier cosa que tenga que cuando haya terminado. Ya se trate de identificadores de archivo de base de datos, conexiones u objetos desechables.

Separado de lo que es el patrón muy práctica de LazyLoad.

Decir que tengo y crea una instancia ObjAde class A. Class Atiene una propiedad pública llamada PropBde class B.

Internamente, PropButiliza la variable privada de _Be incumplimientos a NULL. Cuando PropB.Get()se utiliza, se comprueba para ver si _PropBes nulo y si es así, abre los recursos necesarios para crear instancias de un Ba _PropB. A continuación, devuelve _PropB.

A mi experiencia, esto es un truco muy útil.

Donde la necesidad de nula viene en es si reinicia o cambiar un de alguna manera que el contenido del _PropBeran el niño de los valores anteriores de A, necesitará para disponer y nulos a cabo _PropBde manera LazyLoad puede restablecer a buscar el valor correcto si el código así lo requiere.

Si vas a hacer _PropB.Dispose()y poco después de esperar el cheque nulo para LazyLoad tenga éxito, no será nula, y se le busca en los datos obsoletos. En efecto, debe nula después Dispose()sólo para estar seguro.

Honestamente, quisiera que no fuera así, pero tengo ahora mismo código que exhiben este comportamiento después de una Dispose()en una _PropBy fuera de la función de llamada que hizo el Desechar (y por lo tanto casi fuera de alcance), el puntal privada todavía no es nulo, y los datos rancio sigue ahí.

Con el tiempo, la propiedad será dispuesta nulo, pero que ha sido no determinista desde mi perspectiva.

La razón de la base, como dbkk alude es que el contenedor principal ( ObjAcon PropB) es mantener la instancia de _PropBen alcance, a pesar de la Dispose().

Respondida el 11/04/2012 a las 02:12
fuente por usuario KenF

votos
1

Eche un vistazo a este artículo también: http://www.codeproject.com/KB/cs/idisposable.aspx

En su mayor parte, establecer un objeto como nulo no tiene ningún efecto. La única vez que debe asegurarse de hacerlo es si está trabajando con un "objeto grande", que es uno de tamaño superior a 84K (como mapas de bits).

Respondida el 17/08/2008 a las 05:46
fuente por usuario Scott Dorman

votos
1

Hay algunos casos en los que tiene sentido para las referencias nulas. Por ejemplo, cuando está escribiendo una colección, como una cola de prioridad, y según su contrato, no debe mantener esos objetos vivos para el cliente una vez que el cliente los haya eliminado de la cola.

Pero este tipo de cosas solo importa en colecciones de larga duración. Si la cola no va a sobrevivir al final de la función en la que se creó, entonces importa mucho menos.

En general, no deberías molestarte. Deje que el compilador y GC hagan su trabajo para que pueda hacer el suyo.

Respondida el 05/08/2008 a las 09:46
fuente por usuario Patrick

votos
0

Creo que por el diseño de los ejecutores de GC, no se puede acelerar la GC con anulación. Estoy seguro de que usted preferiría no preocuparse con la forma / GC cuando se ejecuta - tratarlo como esta omnipresente Ser proteger y velar y hacia fuera para usted ... (arcos cabeza hacia abajo, levanta el puño al cielo) .. .

En lo personal, a menudo establecer explícitamente variables para nula cuando he terminado con ellos como una forma de auto-documentación. No declaro, utilizar, a continuación, establece en null tarde - Me nula inmediatamente después de que ya no son necesarios. Yo digo que, de manera explícita, "he terminado oficialmente con usted ... se ha ido ..."

Es necesario dejar sin efecto en un idioma GC'd? No. ¿Es útil para la GC? Quizás sí, quizás no, no lo sé con certeza, por diseño Realmente no puedo controlarlo, y con independencia de la respuesta de hoy con esta versión o que, futuras implementaciones GC podrían cambiar la respuesta fuera de mi control. Además, si / cuando se optimiza a cabo anulación que es poco más que una fantasía comentario si se quiere.

Creo que si eso hace que mi intención más clara a la siguiente pobre tonto que sigue mis pasos, y si "podría" potencialmente ayudar GC veces, entonces vale la pena para mí. Sobre todo me hace sentir ordenada y clara, y Mongo le gusta sentir ordenada y clara. :)

Yo lo veo de esta manera: existen lenguajes de programación para permitir que las personas dan a otras personas una idea de la intención y un compilador de una solicitud de empleo de qué hacer - el compilador convierte esa solicitud en un idioma diferente (a veces varios) para una CPU - la CPU (s) podría dar un comino lo que el lenguaje que utilizó, sus valores de pestañas, comentarios, énfasis estilísticos, nombres de variables, etc. - una CPU todo sobre el flujo de bits que le dice qué registros y códigos de operación y las posiciones de memoria a girar. Muchas cosas escritas en código no se convierten en lo que se consume por la CPU en la secuencia que se especifica. Nuestra C, C ++, C #, Lisp, Babel, ensamblador o lo que es la teoría que en la realidad, escrito como una declaración de trabajo. Lo que se ve no es lo que hay, sí, incluso en lenguaje ensamblador.

Yo entiendo la mentalidad de "cosas innecesarias" (como líneas en blanco) "no son más que ruido y el desorden de código." Ese era yo antes en mi carrera; Entiendo totalmente eso. En este momento me inclino hacia lo que hace que el código más claro. No es como que estoy añadiendo incluso 50 líneas de "ruido" a mis programas - es unas pocas líneas aquí o allá.

Hay excepciones a cualquier regla. En los escenarios con la memoria volátil, una memoria estática, las condiciones de carrera, únicos, el uso de los datos "vieja" y todo ese tipo de pudrición, eso es diferente: hay que gestionar su propia memoria, bloqueo y anulando como propósito porque la memoria no es parte de GC'd el Universo - esperemos que todo el mundo entiende eso. El resto del tiempo con lenguajes GC'd es una cuestión de estilo y no por necesidad o un aumento de rendimiento garantizado.

Al final del día, asegúrese de que entiende lo que es elegible para GC y qué no lo es; bloquear, disponer, y anular apropiadamente; cera, pulir cera; inhala exhala; y para todo lo demás digo: Si se siente bien, hazlo. Su kilometraje puede variar ... como debe ser ...

Respondida el 10/05/2016 a las 10:07
fuente por usuario John

votos
-1

Algunos objetos suponen el .dispose()método que obliga a eliminar el recurso de la memoria.

Respondida el 05/08/2008 a las 09:21
fuente por usuario GateKiller


Aquí podría ser tu PUBLICIDAD