Pregunta

Debe establecer todos los objetos a null (Nothing en VB.NET) una vez que haya terminado con ellos?

Entiendo que en .NET es esencial para disponer de todas las instancias de los objetos que implementan la IDisposable interfaz para liberar algunos recursos, aunque el objeto puede ser todavía algo después de que se dispone (de ahí el isDisposed propiedad en formularios), así que supongo que todavía puede residir en la memoria o al menos en parte?

También sé que cuando un objeto queda fuera del ámbito de aplicación está marcada por la colección listo para el siguiente paso del recolector de basura (aunque esto puede tomar tiempo).

Así que con esto en mente se ajuste a null acelerar el sistema de liberación de la memoria, ya que no tienen que trabajar fuera de que no se alcance y que son malos efectos secundarios?

Artículos de MSDN nunca hacer esto en los ejemplos y en la actualidad puedo hacer esto ya que no puedo ver el daño.Sin embargo, me han llegado a través de una mezcla de opiniones, así que cualquier comentario es útil.

¿Fue útil?

Solución

Karl es absolutamente correcto, no es necesario configurar los objetos a null después de su uso.Si un objeto implementa IDisposable, sólo asegúrese de que usted llame IDisposable.Dispose() cuando haya terminado con ese objeto envuelto en una try..finally, o, un using() el bloque).Pero incluso si usted no recuerde llamar Dispose(), el finaliser método en el objeto debe estar llamando Dispose() para usted.

Pensé que esto era un buen tratamiento:

La excavación en IDisposable

y este

La Comprensión De IDisposable

No hay ningún punto en intentar adivinar la GC y sus estrategias de gestión, porque es auto tuning y opaco.Hubo una buena discusión sobre el funcionamiento interno con Jeffrey Richter en Dot Net Rocas aquí: Jeffrey Richter en el Modelo de Memoria de Windows y Richters libro CLR a través de C# capítulo 20 tiene un gran tratamiento:

Otros consejos

Otra razón para evitar la creación de objetos a null cuando haya terminado con ellos es que en realidad puede mantenerlas vivas durante más tiempo.

por ejemplo,

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 a ser GC d después de la llamada a "Algo", 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 optimizado de distancia de la asignación a null, por lo que tanto los bits de código a ser lo mismo.

No No null objetos.Usted puede comprobar fuera de 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 para poner las cosas en null no hacer nada, excepto sucio su código.

También:

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

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

Si un objeto implementa IDisposable y se almacena en un campo, yo creo que es bueno null, sólo para evitar el uso de los desechado objeto.Los errores de la siguiente ordenación puede ser doloroso:

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

Es bueno null en el campo después de deshacerse de él, y obtener un NullPtrEx a la derecha en la línea donde el campo se utiliza de nuevo.De lo contrario, podría ejecutar en algunos críptico error abajo de la línea (dependiendo de lo que Haceralgo hace).

Es probable que su código no está estructurado con fuerza suficiente si usted siente la necesidad de null variables.

Hay un número de maneras de limitar el alcance de una variable:

Como se ha mencionado por Steve Tranby

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

Del mismo modo, usted puede simplemente utilizar las llaves:

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

Me parece que el uso de llaves sin ningún "título" realmente limpiar el código y ayudar a que sea más comprensible.

La única vez que usted debe establecer una variable a null cuando la variable no salen de su ámbito y que ya no necesita los datos asociados con ella.De lo contrario no es necesario.

En general no hay necesidad de establecer en null.Pero supongamos que usted tiene un Restablecer la funcionalidad de su clase.

Entonces usted podría hacer, porque usted no quiere llamar a dispose dos veces, ya que algunos de los Enajenar no puede ser implementado correctamente y tirar Sistema.ObjectDisposed excepción.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }

este tipo de "no hay necesidad de ajustar los objetos a null después de su uso" no es totalmente exacta.Hay veces que es necesario NULL a la variable después de deshacerse de él.

Sí, SIEMPRE debe llamar a .Dispose() o .Close() en nada de lo que tiene cuando haya terminado.Sea identificadores de archivos, conexiones de base de datos desechables o de objetos.

Aparte de que es muy práctico patrón de LazyLoad.

Decir que tengo y crear instancias ObjA de class A. Class A tiene una propiedad pública denominada PropB de class B.

Internamente, PropB utiliza la variable privada de _B y su valor predeterminado es null.Cuando PropB.Get() se utiliza, se comprueba si _PropB es nulo y si es así, abre los recursos necesarios para crear una instancia de un B en _PropB.A continuación, devuelve _PropB.

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

Donde la necesidad de null viene es si restablecer o cambiar de alguna manera que el contenido de _PropB eran los hijos de los valores anteriores de A, usted tendrá que eliminar Y null fuera _PropB así LazyLoad puede restablecer para obtener el valor correcto SI el código lo requiere.

Si sólo se _PropB.Dispose() y poco después de esperar la verificación null para LazyLoad para tener éxito, no será nulo, y se le busca en datos obsoletos.En efecto, debe null después de Dispose() sólo para estar seguro.

Espero que fuera de otra manera, pero tengo el código de derecho ahora presentan este comportamiento después de un Dispose() en un _PropB y fuera de la función de llamada que hizo el Dispose (y, por tanto, casi fuera de alcance), el privado prop todavía no es nula, y los datos antiguos todavía está allí.

Finalmente, los eliminados de la propiedad será nulo, pero que ha sido no-determinista desde mi punto de vista.

El principal motivo, como dbkk alude es que el contenedor primario (ObjA con PropB) es el mantenimiento de la instancia de _PropB en el ámbito de aplicación, a pesar de la Dispose().

Hay algunos casos en los que tiene sentido para una referencia null.Por ejemplo, cuando estás escribiendo una colección--como una cola de prioridad, y por su contrato, no debe ser mantener los objetos vivos para el cliente después de que el cliente ha quitado de la cola.

Pero este tipo de cosas sólo importa en la larga duración de las colecciones.Si la cola no va a sobrevivir a la final de la función se creó en, a continuación, importa mucho menos.

En un todo, en realidad no debería molestar.Dejar que el compilador y el GC de hacer su trabajo de modo que usted puede hacer suya.

Echa un vistazo a este artículo, así: http://www.codeproject.com/KB/cs/idisposable.aspx

Para la mayor parte, la configuración de un objeto nulo no tiene ningún efecto.La única vez que usted debe asegurarse de hacerlo es si usted está trabajando con un "gran objeto", que es uno de los más grandes que 84K en tamaño (como mapas de bits).

Stephen Cleary explica muy bien en este post: Debo Conjunto de Variables con el valor Null para Ayudar a la Recolección de Basura?

Dice:

La Respuesta Corta, para los Impacientes Sí, si la variable es un campo estático, o si usted está escribiendo un enumerable (método usando rendimiento) o un método asincrónico (el uso de async y await).De lo contrario, no.

Esto significa que en los métodos regulares (no enumerable y no asincrónica), no establece las variables locales, parámetros de método, o los campos de instancia a null.

(Incluso si se está implementando IDisposable.Disponer, que todavía no debe establecer las variables a null).

Lo importante que debemos considerar es Los Campos Estáticos.

Los campos estáticos son siempre objetos raíz, por lo que son siempre se considera "vivo" por el recolector de basura.Si un campo estático hace referencia a un objeto que ya no es necesaria, se debe establecer en null para que el recolector de basura van a tratar como elegibles para la colección.

Configuración de los campos estáticos a null no tiene sentido si todo el proceso se está cerrando.Todo el montón está a punto de ser basura que se recoge en ese momento, incluyendo todos los objetos raíz.

Conclusión:

Los campos estáticos;de eso se trata.Cualquier otra cosa es un pérdida de tiempo.

Creo que por el diseño de la GC ejecutores, no se puede velocidad de hasta GC con la anulación.Estoy seguro de que preferiría que no te preocupes a ti mismo con cómo/cuando GC corre -- el tratamiento de esta omnipresente Siendo proteger y velar por y para usted...(inclina la cabeza hacia abajo, levanta el puño hacia el cielo)...

Yo, personalmente, a menudo explícitamente conjunto de variables a null cuando he terminado con ellos como una forma de auto documentación.Yo no declarar, utilizar, a continuación, establece en null más tarde-me null inmediatamente después de que ya no se necesiten.Estoy diciendo que, explícitamente, "estoy oficialmente hace con usted...se ha ido..."

Es necesario anular en una mesa había un lenguaje?No.Es útil para la GC?Tal vez sí, tal vez no, no se sabe con certeza, por el diseño que realmente no puede controlar, y con independencia de la respuesta de hoy con esta versión o la que, en el futuro GC implementaciones podrían cambiar la respuesta, más allá de mi control.Además, si/cuando el anular está optimizado es poco más que una fantasía comentario si usted va.

Me imagino que si hace que mi intención más clara para la próxima pobre tonto que sigue mis pasos, y si "podría" el potencial de ayudar a GC a veces, vale la pena para mí.Sobre todo me hace sentir ordenada y clara, y Mongo le gusta sentirse ordenada y clara.:)

Yo lo veo como esto:Los lenguajes de programación existen para dejar que la gente a dar a la gente una idea de la intención y de un compilador de una solicitud de trabajo de lo que hacer, el compilador convierte a esa solicitud en un idioma diferente (a veces varios) para una CPU -- la CPU(s) podría dar un puntazo qué idioma utilizado, su ficha configuración, comentarios, estilísticas énfasis, los nombres de las variables, etc.-- una CPU todo sobre el flujo de bits que dice lo de los registros y códigos de operación y ubicaciones de memoria para juguetear.Muchas de las cosas escritas en el código no se conviertan en lo que es consumida por la CPU en la secuencia especificada.Nuestro C, C++, C#, Lisp, Babel, ensamblador o lo que sea es la teoría más que en la realidad, escrito como una declaración de trabajo.Lo que ves no es lo que usted consigue, sí, incluso en el lenguaje ensamblador.

Yo no entiendo la mentalidad de "cosas innecesarias" (como las líneas en blanco) "no son nada, pero el ruido y el desorden del código." Que era yo antes en mi carrera;Entiendo totalmente que.En este momento me inclino hacia la que hace el código más claro.No se como voy a agregar hasta 50 líneas de "ruido" para mis programas, es una pocas líneas aquí o allí.

Hay excepciones a la regla.En los escenarios con la volatilidad de la memoria, de la memoria estática, condiciones de carrera, singleton, el uso de datos "obsoletos" y todo ese tipo de putrefacción, que es diferente:usted NECESITA para administrar su propia memoria, bloqueo y anulando como a propósito, porque la memoria no es parte de la GC gustaría Universo, espero que todo el mundo entiende eso.El resto del tiempo con GC gustaría idiomas es una cuestión de estilo que de necesidad o una garantía de mejora en el rendimiento.

Al final del día, asegúrese de entender lo que es elegible para la GC y lo que no;de bloqueo, disponer, y anular de forma adecuada;limpiar, encerar;inhala, exhala;y para todo lo demás me dicen:Si se siente bien, hazlo.Su kilometraje puede variar...como debería...

Algunos supongamos que el objeto .dispose() método que obliga a que el recurso para ser eliminado de la memoria.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top