2016-04-11 17 views
5

Sto lavorando a un programma che crea grafici interattivi. Tuttavia, il seguente problema si verifica anche se il livello di rendering del programma è disabilitato.C#, perché il GC viene eseguito più volte al secondo?

Su alcune schermate dell'applicazione, in base agli strumenti di diagnostica di Visual Studio 2015, il GC esegue il back to back circa 4 volte al secondo, riducendo le prestazioni della mia applicazione (da 120 fps fino a 15 fps).

Ho scattato alcune snapshot di memoria in attesa di vedere allocazioni impreviste, ma in base alle istantanee ci sono solo una o due allocazioni e raccolte di System.Internal.HandleCollector + HandleType ogni pochi secondi, che sembra essere normale, anche quando il problema non sta succedendo.

Alcune altre cose che ho notato:

  • Questo accade su più macchine.
  • Questo succede con o senza il debugger allegato.
  • La maggior parte del tempo di CPU dell'applicazione è in clr.dll.
  • Il motivo di ogni esecuzione del GC è elencato come "allocazione degli oggetti di piccole dimensioni ", anche quando non sono presenti allocazioni osservabili nelle istantanee.

A questo punto sono perplesso. Qualcuno ha visto accadere questo o sapere dove dovrei iniziare il debug?

+0

Che cosa stai utilizzando per generare i grafici? GDI +? Aggiornate la grafica sul cambio di dati o costantemente? –

+0

Utilizziamo DirectX, tramite SharpDX. I grafici vengono generati una volta, modificati in base all'input dell'utente e disegnati su ogni fotogramma. Ma il problema si verifica ancora anche se il livello di rendering è stato completamente rimosso. –

+0

Non sono sicuro di come la domanda "Come si esegue il debug del GC in esecuzione a causa di allocazioni quando Visual Studio non mostra allocazioni?" non ha "una chiara affermazione del problema" ed è "non utile agli altri lettori". –

risposta

0

È necessario verificare il codice su dove si chiama il GC. Normalmente funziona molto meno di 4 volte al secondo. Allegare con un debugger o un profiler a un'istanza che ha il problema di trovare dove viene chiamato il GC. Forse è in una libreria di terze parti. O un codice che non hai pensato di controllare.

+0

Il built-in nel profiler è il modo in cui ho determinato che era il GC. Il GC non viene mai chiamato dal codice. L'unica libreria di terze parti che utilizziamo è per il rendering e il problema si verifica anche quando il rendering è disabilitato. –

2

tenta di modificare l'app.config con questo e fare una corsa

<configuration> 
    <runtime> 
     <gcServer enabled="true"/> 
    </runtime> 
</configuration> 

dettagli più interessanti su GC è qui https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

+0

Poiché il problema è il GC in esecuzione, e non le prestazioni del GC mentre è in esecuzione, questo non risolverà il problema? –

+0

Questa impostazione cambia il modo in cui e quando i thread si fermano mentre GC sta funzionando. Questa particolare voce di configurazione dice di ritardare la garbage collection. Quindi, hai molta memoria e ti aspetti che la tua app userà solo la memoria. L'allocazione della memoria è veloce in .Net. La raccolta di memoria non utilizzata è lenta. Se hai abbastanza memoria per generare il tuo rapporto, GC aspetterà un buon momento. Provalo e verifica se migliora le prestazioni. –

2

Da https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

Garbage Collection si verifica quando uno dei le seguenti condizioni sono vere:

Il sistema h come poca memoria fisica.

La memoria utilizzata dagli oggetti allocati nell'heap gestito supera una soglia accettabile. Questa soglia viene continuamente regolata durante l'esecuzione del processo.

Viene chiamato il metodo GC.Collect. In quasi tutti i casi, non è necessario chiamare questo metodo, perché il garbage collector viene eseguito continuamente. Questo metodo viene utilizzato principalmente per situazioni e test unici.

Forse si verifica una delle tre condizioni elencate sopra. Sembra che la tua applicazione stia utilizzando molta memoria e quindi Garbage Collection è in esecuzione per provare a ripulire alcuni oggetti per cercare di liberare memoria.

Potrebbe anche essere possibile che GC.Collect() si trovi nel codice da qualche parte e stia facendo girare nuovamente il Garbage Collector.

Here sono alcune linee guida per la risoluzione dei problemi relativi alla garbage collection. Una sezione in particolare sembra riguardare il problema che stai riscontrando. Sotto la sezione contrassegnata come "Problema: l'utilizzo della CPU durante una raccolta di dati inutili è troppo alta", dice:

L'utilizzo della CPU sarà elevato durante una procedura di garbage collection. Se una quantità significativa di tempo di processo viene spesa in una raccolta dati inutili, il numero di raccolte è troppo frequente o la raccolta dura troppo a lungo. Un aumento del tasso di allocazione degli oggetti nell'heap gestito fa sì che la garbage collection si verifichi più frequentemente. La riduzione del tasso di allocazione riduce la frequenza delle raccolte di dati inutili.

È possibile monitorare i tassi di allocazione utilizzando il contatore di prestazioni dei byte allocati/secondo. Per ulteriori informazioni, vedere Contatori delle prestazioni in .NET Framework.

La durata di una raccolta è principalmente un fattore del numero di oggetti che sopravvivono dopo l'allocazione. Il garbage collector deve passare attraverso una grande quantità di memoria se molti oggetti rimangono da raccogliere. Il lavoro per compattare i sopravvissuti richiede molto tempo. Per determinare quanti oggetti sono stati gestiti durante una raccolta, impostare un punto di interruzione nel debugger alla fine di una garbage collection per una generazione specificata.

+0

In base a GC.GetTotalMemory(), vengono utilizzati 10 MB di memoria mentre si verifica il problema. GC.Collect() non viene mai chiamato manualmente. E c'è più di un sacco di memoria fisica. –

+0

Non ti capita di avere GC.Collect ovunque nel tuo codice, vero? Lo terrò anche nella mia risposta. – Tophandour

+0

È già nella tua risposta, è la condizione # 3. –

Problemi correlati