2010-02-27 14 views
19

Come C#, o altri linguaggi per quella materia, di gestire l'allocazione di memoria (e la memoria de-allocazione) tra questi due scenari:C esempio # classe con metodo statico vs utilizzo della memoria classe statica

1.) Un metodo su viene invocata una classe statica.

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

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

2.) Un metodo viene richiamato su un'istanza, che quindi non rientra nell'ambito.

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

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

Suppongo che la classe statica è caricato, e rimane, in memoria; mentre l'istanza di classe soccombe alla raccolta dei rifiuti al tempo libero di C#. Ci sono dei pro o contro in questi due paradigmi? C'è mai un momento in cui si ha una classe che non ha mai bisogno di essere istanziata (cioè una sorta di caricatore di risorse o factory), ma si usa comunque la seconda metodologia per sfruttare la garbage collection?

La parte importante della mia domanda è se il primo paradigma, pur essendo concettualmente corretto in alcune circostanze, possa rimanere senza memoria.

+3

Il secondo esempio non mi sembra corretto. La chiamata a un metodo statico richiede che sia preceduta dal nome della classe. per esempio. 'Loader.Load()' & ** not ** 'nuovo Loader(). Load()' – shahkalpesh

+0

Hai ragione, Shah - non hai bisogno di un'istanza per chiamare un metodo statico. Questo è un po 'il punto :) –

+0

ah, voi ragazzi avete ragione, grazie, l'ho riscritto per ottenere la carne della domanda che stavo tentando di chiedere. – jtb

risposta

8

tuo secondo esempio non funziona, quindi cerchiamo di esplorare le opzioni reali:

1.) Un metodo su una classe statica viene richiamato.

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

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

2.) Viene richiamato un metodo statico in una classe non statica.

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

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

3.) Un metodo istanza viene richiamato su un'istanza

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

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

I primi due sono gli stessi. Chiamare un metodo statico è lo stesso indipendentemente se la classe è statica o meno.

La terza opzione crea un'istanza della classe nell'heap. Poiché la classe non ha membri di dati, sarà solo qualcosa come 16 byte. Alla fine verranno raccolti dei rifiuti, ma a causa delle piccole dimensioni non importa molto quando ciò accade.

Anche la chiamata di un metodo di istanza è leggermente diversa da un metodo statico. Viene inviato un riferimento all'istanza della classe, a cui è possibile accedere tramite la parola chiave this. In questo caso fa poca differenza in quanto non ci sono dati reali nell'oggetto da accedere.

+0

L'ingombro di memoria di un programma C# cambia quando un'istanza di un oggetto è raccolta dati inutili (oltre ai dati del campo Istanza, ovviamente), c'è mai uno scaricamento delle informazioni di tipo che si verificano mai? Per dirla in modo colloquiale, C# eseguirà mai qualsiasi ottimizzazione come "Oh, nessuna di queste classi ha attualmente istanze, non ne ho più bisogno, scaricherò i dati di tipo raw dal programma e mi libererò un po 'di memoria "? – jtb

+0

@jtb: No, per quanto ne so, .NET non scaricherà un assembly che è stato caricato una volta. – Guffa

+0

@jtb GC libererà solo la memoria della classe solo se non ha riferimenti/handle ecc e solo quando le risorse di memoria del sistema operativo sono scarse. –

1

Un metodo statico, campo, proprietà o evento è richiamabile su una classe anche se non è stata creata alcuna istanza della classe.

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

In questo senso i metodi statici si comporta proprio come farebbe se è stato utilizzato dal di dentro un'istanza di classe: è ambito per il tipo.

+0

sì, sry, il mio esempio soffre di essere scritto male per illustrare la mia domanda. Non so se questa è una buona etichetta, perché hai ragione, ma dovrò riformulare leggermente la mia domanda per fare la domanda che volevo davvero. – jtb

+0

Dato che un membro statico ha un ambito per il tipo, non penso che l'utilizzo della memoria cambierà solo perché lo chiami all'interno di un'istanza di quel tipo. –

1

Il secondo modulo crea un oggetto temporaneo Loader (che è molto economico). Dovrai sempre caricare la classe Loader, indipendentemente dall'approccio scelto.

Ci sono pochissime prestazioni (risparmio di memoria) da ottenere qui. Normalmente si sceglie un membro statico in una classe statica se non esiste uno "stato" necessario al di fuori dei metodi locali vars.

+0

@Henk: il 2 ° esempio non verrà compilato in C#. destra? – shahkalpesh

+0

@Shah Si compilerà. nota 2 ° esempio non sta chiamando un metodo statico! Chiama un normale metodo pubblico all'interno di un'istanza che viene quindi raccolta dalla spazzatura poiché non viene mai più aggiornata. –

+0

sì, le persone sono confuse perché il mio post originale aveva il metodo nel secondo esempio contrassegnato come statico, l'ho modificato. – jtb

0

Non riesco a trovare nessun fonti per questo, ma dalla mia conoscenza di programmazione, quando si refernce una classe (non statico), la sua struttura viene caricato in memoria

Creazione di un'istanza di una classe solo per chiamare un metodo , sprecherebbe un sacco di potenza di elaborazione (a causa della creazione di un'istanza, dell'assegnazione della memoria e della raccolta dei dati inutili).

Invece di mantenere la definizione, e poi sopra, un'istanza. Perché non mantenere solo la definizione (statica).

Fintantoché non si memorizzano dati in variabili statiche, il metodo statico dovrebbe occupare la stessa quantità di memoria della definizione del metodo non statico. Ma usando un metodo statico, solo il metodo sarà tenuto in memoria ed essere pronto per essere chiamato ogni volta che è necessario senza creare istanze. Laddove, se il metodo non è statico, dovrà essere istanziato (utilizzando la memoria e la potenza di elaborazione) e la garbage collection (liberando memoria e usando cpu) quindi è decisamente meglio usare un membro statico. Questo è quello che sono lì per.

+0

Quando si fa riferimento a una classe statica, la mia comprensione è che C# esegue l'inizializzatore statico, carica i campi statici in memoria e carica i dati di tipo (struttura di classe) in memoria, mantenendoli lì per la durata del runtime del programma. Quando viene creata un'istanza di una classe, il costruttore viene elaborato, la memoria viene allocata per i campi di istanza e il tipo di dati viene caricato in memoria (se non è già presente). Tuttavia, quando un'istanza di una classe lascia l'ambito, i dati vengono infine ereditati dall'etere, ma i dati di tipo vengono mai rilasciati? – jtb

Problemi correlati