2010-02-27 15 views
19

¿Cómo C#, o en otros idiomas, para el caso, gestionar la asignación de memoria (y la memoria de asignación) entre estas dos situaciones:C instancia # clase con métodos estáticos vs uso de memoria clase estática

1.) Un método de se invoca una clase estática.

public Program { 
    Foo foo = Loader.load(); 
} 

public static Loader { 
    public static Foo load() { 
     return new Foo(); 
    } 
} 

2.) Se invoca un método en una instancia, que luego cae fuera del alcance.

public Program { 
    Foo foo = new Loader().load(); 
} 

public Loader { 
    public Foo load() { 
     return new Foo(); 
    } 
} 

Supongo que la clase estática está cargada y permanece en la memoria; mientras que la instancia de clase sucumbe a la recolección de basura en el ocio de C#. ¿Hay algún pros o contras para estos dos paradigmas? ¿Hay alguna vez en que tenga una clase que nunca necesite ser instanciada (es decir, algún tipo de cargador de recursos o fábrica), pero utiliza la segunda metodología de todos modos para aprovechar la recolección de basura?

La parte importante de mi pregunta es si o no el primer paradigma, mientras que ser conceptualmente correcto en algunas circunstancias, pueden sufrir de aferrarse a la memoria innecesariamente.

+3

El segundo ejemplo me parece incorrecto. Llamar a un método estático requiere un prefijo con nombre de clase. p.ej. 'Loader.Load()' & ** not ** 'new Loader(). Load()' – shahkalpesh

+0

Tienes razón, Shah: no necesitas una instancia para llamar a un método estático. Ese es el punto :) –

+0

ah, ustedes tienen razón, gracias, lo he modificado para llegar a la esencia de la pregunta que estaba tratando de hacer. – jtb

Respuesta

8

Su segundo ejemplo no funciona, así que vamos a explorar las opciones reales:

1.) Un método en una clase estática se invoca.

public Program { 
    Foo foo = Loader.Load(); 
} 

public static Loader { 
    public static Foo Load() { 
     return new Foo(); 
    } 
} 

2.) Un método estático en una clase no estática se invoca.

public Program { 
    Foo foo = Loader.Load(); 
} 

public Loader { 
    public static Foo Load() { 
     return new Foo(); 
    } 
} 

3.) un método de instancia se invoca en una instancia

public Program { 
    Foo foo = new Loader().Load(); 
} 

public Loader { 
    public Foo Load() { 
     return new Foo(); 
    } 
} 

Los dos primeros son el mismo. Llamar a un método estático es el mismo independientemente de si la clase es estática o no.

La tercera opción creará una instancia de la clase en el montón. Como la clase no tiene miembros de datos, solo será algo así como 16 bytes. Eventualmente se recolectará basura, pero debido al tamaño pequeño no importa mucho cuando eso sucede.

Llamar a un método de instancia también es ligeramente diferente de un método estático. Se envía una referencia a la instancia de clase, a la que puede acceder a través de la palabra clave this. En este caso, hay poca diferencia ya que no hay datos reales en el objeto al que acceder.

+0

¿Cambia la huella de memoria de un programa C# cuando una instancia de un objeto es basura recolectada (además de los datos del campo de instancia, obviamente), hay alguna descarga de la información Tipo que alguna vez se lleva a cabo? Para ponerlo coloquialmente, ¿alguna vez C# realizará alguna optimización como "Oh, ninguna de estas clases actualmente tiene instancias, ya no las necesito, descargaré los datos sin formato del programa y me ahorraré algo de memoria "¿?" – jtb

+0

@jtb: No, que yo sepa, .NET no descargará un conjunto que se cargó una vez. – Guffa

+0

@jtb GC solo liberará la memoria que tome su clase solo si no tiene referencias/controladores, etc. y solo cuando los recursos de memoria del sistema operativo son escasos. –

1

Un método estático, campo, propiedad o evento es exigible en una clase, incluso cuando se ha creado ninguna instancia de la clase.

http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx

Así que en ese sentido sus métodos estáticos se comporta del mismo modo que lo haría si se ha utilizado desde dentro de una instancia de clase: que tiene como alcance el tipo.

+0

sí, sry, mi ejemplo adolece de estar mal escrito para ilustrar mi pregunta. No sé si esto es una etiqueta SO, porque estás en lo correcto, pero voy a tener que reformular mi pregunta ligeramente para poder hacer la pregunta que realmente quería. – jtb

+0

Dado que un miembro estático tiene un alcance del tipo, no creo que el uso de la memoria vaya a cambiar solo porque lo llame dentro de una instancia de ese tipo. –

1

La segunda forma crea una Loader objeto temporal (que es muy barato). Siempre tendrá que cargar la clase Loader, sin importar qué enfoque elija.

Aquí se obtiene muy poco rendimiento (ahorro de memoria). Normalmente elegirías un miembro estático en una clase estática si no se necesita un 'estado' fuera de los métodos locales vars.

+0

@Henk: El segundo ejemplo no se compilará en C#. ¿derecho? – shahkalpesh

+0

@Shah Se compilará. nota 2do ejemplo no es llamar a un método estático! Está llamando a un método público normal dentro de una instancia que luego es recolectada como basura, ya que nunca se vuelve a ingresar. –

+0

sí, la gente está confundida porque mi publicación original tenía el método en el segundo ejemplo marcado como estático, lo edité. – jtb

0

no puedo encontrar ninguna fuente para esto, pero a partir de mis conocimientos de programación, cuando refernce una clase (no estática), su estructura se carga en memoria

Creación de una instancia de una clase sólo para llamar a un método , perderá una gran cantidad de poder de procesamiento (debido a la creación de una instancia, la asignación de memoria y la recolección de basura).

En lugar de mantener la definición, y luego en la parte superior, una instancia. ¿Por qué no mantener la definición (estática)?

Siempre que no almacene datos en variables estáticas, su método estático debería ocupar la misma cantidad de memoria que su definición de método no estático. Pero utilizando un método estático, solo el método se mantendrá en la memoria y estará listo para ser llamado siempre que lo necesite sin crear instancias. Donde si, si el método no es estático, necesitará una instancia (usando la memoria y la potencia de procesamiento) y la basura recolectada (liberando la memoria y usando la CPU) por lo tanto, es definitivamente mejor usar un miembro estático. Eso es para lo que están allí.

+0

Cuando se hace referencia por primera vez a una clase estática, entiendo que C# ejecuta el inicializador estático, carga campos estáticos en la memoria y carga los datos de tipo (estructura de clases) en la memoria, manteniéndolos allí mientras dura el tiempo de ejecución del programa. Cuando se crea una instancia de una clase, el constructor se procesa, la memoria se asigna para los campos de instancia y los datos de tipo se cargan en la memoria (si no están ya allí). Sin embargo, cuando una instancia de una clase deja alcance, sus datos se legan finalmente al éter, pero ¿los datos de Tipo se publican alguna vez? – jtb

Cuestiones relacionadas