2011-12-06 10 views
12

Stavo leggendo sul GC nel libro CLR via C#, in particolare su quando il CLR vuole iniziare una raccolta. Capisco che deve sospendere i thread prima che si verifichi una raccolta, ma menziona che deve farlo quando il puntatore dell'istruzione di thread raggiunge un punto sicuro. Nei casi in cui non si trova in un punto sicuro, tenta di raggiungerlo rapidamente, e lo fa per hijacking il thread (inserendo un puntatore a funzione speciale nello stack di thread). Va tutto bene e dandy, ma pensavo che i thread gestiti di default fossero sicuri?Comportamento del GC e dirottamento del thread CLR

Inizialmente avevo pensato che si sarebbe potuto riferire a thread non gestiti, ma il CLR consente ai thread non gestiti di continuare a essere eseguiti perché gli oggetti utilizzati dovrebbero essere stati bloccati comunque.

Quindi, cos'è un safe point in un thread gestito e in che modo il GC può determinare di cosa si tratta?

EDIT:

non credo mi veniva abbastanza specifico. In base a this MSDN article, anche quando viene chiamato Thread.Suspend, la discussione non verrà effettivamente sospesa fino al raggiungimento di safe point. Si prosegue affermando inoltre che un safe point è un punto nell'esecuzione di thread in cui è possibile eseguire una garbage collection.

Penso di non essere stato chiaro nella mia domanda. Mi rendo conto che un Thread può essere sospeso solo in un punto sicuro e devono essere sospesi per un GC, ma non riesco a trovare una risposta chiara su quale sia un punto sicuro. Cosa determina un punto nel codice come sicuro?

+2

Sicuro dal CLR, non dal CLR. –

risposta

13

'Punti sicure' sono dove siamo:

  1. Non in un blocco catch.
  2. Non
  3. all'interno di un finalmente
  4. non all'interno di un blocco
  5. non all'interno di chiamata p/invoke'd (in codice gestito). Non è in esecuzione codice non gestito nel CLR.
  6. L'albero della memoria è percorribile.

Punto # 5 è un po 'di confusione, ma ci sono momenti in cui l'albero della memoria non sarà percorribile. Ad esempio, dopo l'ottimizzazione, il CLR può creare un nuovo oggetto e non assegnarlo direttamente a una variabile. Secondo il GC, questo oggetto sarebbe un oggetto morto pronto per essere raccolto. Il compilatore istruirà il GC quando questo accade di non eseguire ancora GC.

Ecco un post sul blog su MSDN con un po 'più di informazioni: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

EDIT: Be', signore, mi sbagliavo # 4. Vedi here nella sezione "Punto sicuro". Se ci si trova all'interno di una sezione di codice p/invoke (non gestito), è consentita l'esecuzione fino a quando non ritorna nuovamente al codice gestito.

Tuttavia, in base a this MSDN article, se ci si trova in una parte non gestita del codice CLR, non è considerato sicuro e attenderanno fino a quando il codice non tornerà gestito. (Ero vicino, almeno).

+0

Ah, questo ha molto senso, in particolare # 5, l'intera struttura della memoria deve essere in uno stato verificabile affinché GC esegua una raccolta. È un concetto molto semplice quando hai la risposta, è stato solo arrivare lì che stavo avendo problemi con.Grazie! –