Operazioni rapide da verificare quando si riscontrano livelli di memoria elevati in ASP.NET

Questo articolo descrive le operazioni rapide da controllare quando si riscontra una memoria elevata in Microsoft ASP.NET.

Versione originale del prodotto: ASP.NET
Numero KB originale: 893660

Questo articolo inizierà con alcuni problemi comuni, azioni per risolvere questi problemi e una breve spiegazione del motivo per cui queste situazioni possono causare problemi.

ASP.NET colonna Support Voice

Nella colonna Voce di supporto di aprile 2005 è stato fornito inavvertitamente un collegamento al file errato. Anziché collegarsi a un download per il servizio Web, è stato collegato al file XML restituito dal servizio Web. Il collegamento è stato corretto. Per esaminare l'articolo con il file corretto allegato, vedere Aggiornamenti delle pagine dinamiche con XMLHTTP.

Che cosa è considerato memoria elevata

Ovviamente, questa domanda dipende dal volume e dall'attività di applicazioni specifiche. In generale, la memoria elevata è quando la memoria del processo di lavoro ASP.NET (Aspnet_wp.exe) o del processo di lavoro (IIS) di Internet Information Services (W3wp.exe) aumenta costantemente e non torna a un livello confortevole.

In generale, un livello confortevole sarebbe inferiore a 600 MB nello spazio di indirizzi di memoria utente predefinito di 2 GB. Una volta che il livello di memoria è superiore a quello confortevole, stiamo facendo meno di quanto dovremmo essere. Questo comportamento può influire su altre applicazioni in esecuzione nel sistema.

La chiave consiste nel comprendere alcune applicazioni che richiedono più memoria di altre. Se si superano questi limiti, è possibile aggiungere più memoria o aggiungere un altro server alla Web farm o prendere in considerazione una Web farm. La profilatura è consigliata anche in questi casi. Consente agli sviluppatori di creare applicazioni più snella. In questo articolo viene esaminata una situazione in cui si osserva costantemente l'aumento della memoria fino a quando il server non smette di eseguire le prestazioni.

Configurazione dell'applicazione per il debug

Un motivo per cui la memoria elevata visualizzata qui in Supporto è molto quando si dispone di debug, traccia o entrambi abilitati per l'applicazione. L'abilitazione del debug e della traccia è necessaria quando si sviluppa l'applicazione. Per impostazione predefinita, quando si crea l'applicazione in Visual Studio .NET, nel file Web.config verrà visualizzato l'attributo seguente:

<compilation
 ...
 debug="true"
 />

o

 <trace
 enabled="true"
 ...
 />

Inoltre, quando si esegue una compilazione finale dell'applicazione, assicurarsi di farlo in modalità rilascio, non in modalità debug. Una volta eseguito l'ambiente di produzione, il debug non dovrebbe più essere necessario. Può davvero rallentare le prestazioni e mangiare la memoria. L'impostazione di questo attributo implica la modifica di alcuni aspetti relativi alla modalità di gestione dell'applicazione.

Prima di tutto, la compilazione batch verrà disabilitata, anche se è impostata in questo compilation elemento. Significa che si crea un assembly per ogni pagina dell'applicazione in modo da poterlo suddividere. Questi assembly possono essere sparsi in modo casuale nello spazio di memoria, rendendo più difficile trovare lo spazio contiguo per allocare memoria.

In secondo luogo, l'attributo executionTimeout (<elemento httpRuntime>) è impostato su un numero elevato, ignorando il valore predefinito di 90 secondi. Non è possibile eseguire il debug perché non è possibile avere il timeout dell'applicazione mentre si esegue un'istruzione dettagliata del codice per trovare gli errori. Tuttavia, si tratta di un rischio significativo nell'ambiente di produzione. Significa che se si dispone di una richiesta non autorizzata per qualsiasi motivo, si tratterà di un thread e continuerà qualsiasi comportamento dannoso per giorni invece di pochi minuti.

Infine, si creeranno altri file nella cartella File temporanei ASP.NET . E (Spazio System.Diagnostics.DebuggableAttributedei nomi System.Diagnostics viene aggiunto a tutto il codice generato, che può causare una riduzione delle prestazioni.

Se non si ottiene nient'altro da questo articolo, spero di ottenere queste informazioni. Lasciare abilitato il debug non è valido. Questo comportamento viene visualizzato troppo spesso ed è così facile da cambiare. Ricordarlo può essere impostato a livello di pagina. Assicurarsi che tutte le pagine non siano impostate.

Concatenazione di stringhe

Esistono applicazioni che compilano l'output HTML usando il codice lato server e creando solo una stringa HTML di grandi dimensioni da inviare al browser. Va bene, ma se si compila la stringa usando + e & concatenazione, è possibile che non si sappia quante stringhe di grandi dimensioni si sta creando. Ad esempio:

string mystring = "<html>";
mystring = mystring + "<table><tr><td>";
mystring = mystring + "First Cell";
mystring = mystring + "</td></tr></table>";
mystring = mystring + "</html>";

Questo codice sembra abbastanza innocuo, ma ecco cosa si sta archiviando in memoria:

<html>
<html><table><tr><td>
<html><table><tr><td>First Cell
<html><table><tr><td>First Cell</td></tr></table>
<html><table><tr><td>First Cell</td></tr></table></html>

Si potrebbe pensare di archiviare solo l'ultima riga, ma si archiviano tutte queste righe. È possibile vedere come potrebbe uscire dalla mano, soprattutto quando si crea una tabella di grandi dimensioni, ad esempio eseguendo un ciclo attraverso un recordset di grandi dimensioni. Se si tratta di ciò che si sta facendo, usare la System.Text.StringBuilder classe , in modo da archiviare solo la stringa di grandi dimensioni. Vedere Usare Visual C# per migliorare le prestazioni di concatenazione delle stringhe

.NET Framework Service Pack 1 (SP1)

Se non si esegue ancora .NET Framework SP1, installare questo SP se si verificano problemi di memoria. Non vado in dettaglio, ma fondamentalmente, con SP1 stiamo allocando la memoria in modo molto più efficiente. Fondamentalmente, stiamo allocando 16 MB alla volta per oggetti di grandi dimensioni anziché 64 MB alla volta. Abbiamo tutti spostato, e tutti sappiamo che possiamo comprimere molto di più in un'auto o camion se usiamo molte piccole scatole piuttosto che poche grandi scatole. È l'idea qui.

Non aver paura di riciclare periodicamente

I pool di applicazioni vengono riciclati in IIS ogni 29 ore per impostazione predefinita. Il processo di Aspnet_wp.exe continuerà fino a quando non si termina l'attività, si riavvia IIS o si riavvia il computer. Questo comportamento significa che questo processo potrebbe essere in esecuzione per mesi. È consigliabile che alcune applicazioni riavviino il processo di lavoro ogni paio di giorni o così via, in un momento conveniente.

Domande da porsi

Le precedenti erano tutte le cose che è possibile correggere rapidamente. Tuttavia, se si verificano problemi di memoria, porsi queste domande:

  • Uso molti oggetti di grandi dimensioni? Più di 85.000 KB vengono archiviati in un heap di oggetti di grandi dimensioni.

  • Sto archiviando gli oggetti nello stato sessione? Questi oggetti rimarranno in memoria per molto più tempo che se li usi e li elimini.

  • Uso l'oggetto Cache ? Quando viene usato con saggezza, è un grande vantaggio per le prestazioni. Ma quando viene usato senza senso, si finisce con molta memoria usata che non viene mai rilasciata.

  • Si torna recordsets troppo grandi per un'applicazione Web? Nessuno vuole esaminare 1.000 record in una pagina Web. È consigliabile progettare l'applicazione in modo che non si ottengano mai più di 50-100 record in un unico viaggio.

Debug

Non riesco a configurare WinDbg. Tuttavia, è possibile usare i comandi seguenti per vedere che cos'è esattamente nella memoria, se si desidera risolvere problemi più complessi.

!eeheap -gc

Questo comando mostrerà la quantità di memoria gestita disponibile. Se questo valore è elevato, è necessario creare il codice gestito.

!dumpheap -stat

L'esecuzione di questo comando richiederà molto tempo, anche se la memoria è grande. Ma questo comando fornirà un elenco di tutti gli oggetti, il numero di ogni tipo e la quantità di memoria in uso. Ad esempio, per la StringBuilder classe verranno visualizzati molti System.String oggetti.

Dopo aver trovato un oggetto che richiede molta memoria, esaminare ulteriormente usando il comando seguente:

!do <addr>

È possibile ottenere l'indirizzo dell'oggetto che si sta cercando nel dumpheap comando .

Si tenterà di incorporare altri modi per usare questo strumento di diagnostica per situazioni specifiche in queste colonne. Fateci sapere se stiamo facendo un buon lavoro!

Articoli su memoria e prestazioni

Garbage Collector Basics and Performance Hints (Concetti di base di Garbage Collector e suggerimenti per le prestazioni)

Sviluppo di applicazioni ASP.NET ad alte prestazioni

ASP.NET Monitor prestazioni e quando avvisare gli amministratori

Miglioramento delle prestazioni e della scalabilità delle applicazioni .NET