2009-05-12 14 views

risposta

19

Gli oggetti a cui fanno riferimento le variabili statiche vengono raccolti solo quando il file pertinente AppDomain viene raccolto. Nelle applicazioni client, spesso c'è solo un singolo AppDomain che vive per la durata del processo. (Un'eccezione è quando l'applicazione utilizza un plug-in architettura -. Differente plug-in possono essere caricati in diversi AppDomain s e la AppDomain possono essere scaricati in seguito)

In ASP.NET, "AppDomain riciclo" avviene periodicamente (per vari motivi) - quando questo si verifica e le variabili statiche all'interno di quello AppDomain non funzioneranno più come radici GC e quindi non impediranno che gli oggetti vengano sottoposti a garbage collection.

Se si è preoccupati che un oggetto venga considerato come garbage collector mentre si ha ancora un riferimento tramite una variabile statica, è possibile rilassarsi. Mentre è possibile accedere all'oggetto, questo non sarà raccolto.

+0

Questo non crea una grande inefficienza? Spesso creo metodi di supporto statici privati. Oppure, tutti i metodi di estensione. Mi chiedo quanti ricordi consumano? Se ho un metodo di supporto per un oggetto, è meglio lasciare semplicemente l'helper come un'istanza in modo che venga raccolto? –

+0

@ P.Brian.Mackey: Se hai metodi statici, quale memoria stai immaginando di essere consumata? Se hai variabili * statiche *, hai lo stato globale, che spesso è una cattiva idea per iniziare. Ma i metodi stessi sono una questione diversa. –

+0

Il mio errore. Ho assunto che i metodi vengano creati sullo stack/heap come fanno le variabili. Apparentemente non è il caso. –

5

I membri non sono raccolti ... Gli oggetti lo sono.
Quindi se si imposta il rif. Digitare static member su null, verrà raccolto qualsiasi oggetto a cui si stava puntando in precedenza. In caso contrario, si bloccherà fino a quando AppDomain non si arresta (ogni AppDomain ha il proprio set di elementi statici)

0

Un membro statico a un tipo di riferimento è un riferimento, che può o meno puntare a un'istanza. Se punta a un'istanza, detta istanza non verrà raccolta fino a quando il membro statico non viene scaricato. Se il tipo è caricato in un AppDomain specifico, è possibile scaricarlo. Altrimenti succede solo quando l'applicazione è terminata.

1

La risposta breve ... No; tutte le attuali implementazioni del garbage collector .NET non raccoglieranno oggetti fortemente referenziati dai campi dei membri della classe statici, fino a quando il dominio dell'applicazione a cui sono associati i riferimenti forti del campo membro della classe statica viene rimosso.

La risposta più lunga ... Potenzialmente sì; il garbage collector basa la sua decisione di raccogliere un oggetto sulla raggiungibilità dell'oggetto, non su riferimenti (forti o deboli) all'oggetto. In teoria, se il garbage collector potesse determinare che nessun codice richiederebbe mai un determinato oggetto da un certo punto in poi (cioè, l'oggetto non è raggiungibile da alcun percorso di codice), il GC sarebbe autorizzato a raccogliere quell'oggetto, anche se fosse ancora fortemente referenziato da campi di membri statici della classe. Questo è perfettamente ammissibile, dal momento che non si noterà mai, poiché nessun codice proverebbe mai ad accedere al campo membro della classe statica che contiene il riferimento all'oggetto. Potresti chiederlo, quindi perché mi interessa se non accederai mai più all'oggetto tramite uno dei riferimenti forti a cui tengo? La ragione per cui ti interessi sono gli effetti collaterali. Ad esempio, è possibile assumere assegnando a un campo membro della classe statica un riferimento a un oggetto SafeHandle, che rappresenta una risorsa non gestita, che l'oggetto SafeHandle non verrà mai chiuso e quindi manterrà l'oggetto "non gestito" che rappresenta vivo. Questo è vero solo per le attuali implementazioni del GC. Un'implementazione futura del GC potrebbe raccogliere oggetti fortemente referenziati da campi di membri di classi statiche se tali oggetti non fossero più raggiungibili da uno qualsiasi dei rimanenti codici di programma.