Applicazioni .NET ed utilizzo della memoria

venerdì 24 giugno 2011 - 09.01
Tag Elenco Tags  .NET 3.5  |  .NET 4.0  |  Windows Server 2008 R2  |  SQL Server 2008 R2

lukepet Profilo | Junior Member

Salve, ho alcuni dubbi su un progetto che mi trovo a gestire e volevo da voi alcuni consigli in base alle vostre esperienze. Vi spiego subito la situazione.
Ho un server con 12Gb di RAM e sistema operativo Windows Server 2008 R2; su tale server risiede un'applicazione di gestione delle vendite sviluppata in WPF e che utilizza NHibernate (2.1.2) per la persistenza dei dati (il DBMS è SQL Server 2008). Al server accedono contemporaneamente via VPN dai 30 ai 40 utenti, che utilizzano l'applicazione in Desktop Remoto.

In questi giorni stavo monitorando il consumo di risorse nei momenti in cui lavorano tutti all'applicazione ed ho visto che per ogni utente la mia applicazione occupa dai 300 ai 500 mb; tale situazione sembra ridurre la memoria disponibile per SQL Server (che inizialmente ho visto essere intorno ai 2Gb, mentre nei momenti di massimo carico l'ho vista scendere a 400mb) e mi chiedevo se questo potesse incidere sulle performance nelle operazioni di lettura/scrittura dati nel db. Inoltre ho visto che praticamente il sistema raggiunge quasi 100% della memoria in uso ed ho paura che questa situazione "limite" possa portare ad ulteriori problematiche.

Ho iniziato ad analizzare la mia applicazione per rendermi conto di quale possa essere la causa di tale consumo di memoria e mi sono reso conto che in parte ciò è dovuto alla cache di NHibernate. Nell'applicazione infatti sono presenti delle manutenzioni che trattano una gran mole di dati e, nel momento in cui carico i dati, la memoria in uso per il singolo processo cresce di molto. La cosa che non mi convince è che se chiudo la form di manutenzione di tali dati la memoria rimane comunque allocata (e credo che ciò sia dovuto al fatto che i dati rimangono comunque nella cache di NHibernate), per poi essere riciclata automaticamente quando ci sono nuove richieste.

Alla luce di ciò le mie domande sono...

In una situazione del genere mi devo preoccupare del fatto che la memoria in uso del sistema sia quasi il 100%? o sarebbe oppurtuno estendere la RAM?
E' normale che la mia applicazione non rilasci immediatamente la memoria allocata in seguito al caricamento dei dati? Il riciclo della memoria è gestito automaticamente del sistema?
Sarebbe opportuno che nella configurazione di SQL Server prevedessi un limite minimo di memoria assegnata al processo?
Come faccio a rendermi conto se sono effettivamente in una situazione di criticità?
In base alle vostra esperienze personali avete dei consigli da darmi in merito?

Vi ringrazio in anticipo per informazione.

alx_81 Profilo | Guru

>Salve,
Ciao

>In questi giorni stavo monitorando il consumo di risorse nei
>momenti in cui lavorano tutti all'applicazione ed ho visto che
>per ogni utente la mia applicazione occupa dai 300 ai 500 mb;
>tale situazione sembra ridurre la memoria disponibile per SQL
>Server (che inizialmente ho visto essere intorno ai 2Gb, mentre
>nei momenti di massimo carico l'ho vista scendere a 400mb) e
>mi chiedevo se questo potesse incidere sulle performance nelle
>operazioni di lettura/scrittura dati nel db. Inoltre ho visto
>che praticamente il sistema raggiunge quasi 100% della memoria
>in uso ed ho paura che questa situazione "limite" possa portare
>ad ulteriori problematiche.
C'è da premettere che SQL Server, così come tutti i DBMS alloca il massimo di memoria possibile per tutte le informazioni che esso deve "appoggiare" proprio per lavorare il più possibile in memoria, appunto. La cache, ad esempio, quella da cui legge anche i piani di esecuzione è in memoria. In generale tutto quello che può mettere in memoria viene messo in memoria.
Una delle best practices per SQL Server è quella di lasciarlo da solo su una sua macchina dedicata, proprio per incrementare le prestazioni e ridurre l'io verso il disco. Quindi di partenza, direi che l'architettura che hai di certo tende a disturbare e non poco il tuo DB Server. Poi, l'aumento della memoria allocata dall'applicazione è effettivamente molto alto. Nella realtà che sto seguendo il SQL è su di una macchina dedicata, il client, scaricabile è leggero sui "terminali" e il server (nel mio caso WCF) non disturba la memoria usata sul DB Server, essendo installato su di una ulteriore macchina.
Se proprio non puoi permetterti di avere due macchine distinte per l'app server e il DB Server, controlla bene con tool di performance sulla memoria che non ci siano leak, perchè il traffico nella mia realtà è elevato (arrivo ad avere anche qualche migliaio di utenti connessi in certi momenti) e non ho quell'occupazione di memoria. Controlla bene se tutti gli oggetti sono stati "disposati" ed, in generale, se devi far usare in terminal l'app, non pomparla di grafica WPF che è molto pesante e ancora ha dei problemi di leak da gestire in maniera meticolosa. Tutte le eventuali animazioni, le eventuali memorie di appoggio per il client inficiano sicuramente sulla RAM che serve tanto a SQL.

>Ho iniziato ad analizzare la mia applicazione per rendermi conto
>di quale possa essere la causa di tale consumo di memoria e mi
>sono reso conto che in parte ciò è dovuto alla cache di NHibernate.
eh sì, possibile, e il fatto che stia sul server dove risiede SQL non è bello.

>In una situazione del genere mi devo preoccupare del fatto che
>la memoria in uso del sistema sia quasi il 100%? o sarebbe oppurtuno
>estendere la RAM?
SQL prende tutto e rilascia all'occorrenza, quindi non c'è da preoccuparsi del 100% ma del fatto che a SQL basti quella che gli rimane. E dipende da alcuni performance counters da analizzare.
http://msdn.microsoft.com/en-us/library/ms176018.aspx
http://blogs.msdn.com/b/teekamg/archive/2007/11/06/sql-server-memory-related-performance-counters.aspx

>E' normale che la mia applicazione non rilasci immediatamente
>la memoria allocata in seguito al caricamento dei dati? Il riciclo
>della memoria è gestito automaticamente del sistema?
no, il framewoek fa quello che può, ma la domanda che ti dovresti fare è: "disalloco tutto per bene?", "uso le using nel posto giusto?", "implemento la IDisposable dove serve?", "faccio in modo che non esistano canali o connessioni appese che creano dipendenze per cui non riesco a disallocare un oggetto?"..

>Sarebbe opportuno che nella configurazione di SQL Server prevedessi un limite minimo di memoria assegnata al processo?
io gli lascerei il massimo e sposterei l'app.

>Come faccio a rendermi conto se sono effettivamente in una situazione di criticità?
coi contatori di cui sopra.

>Vi ringrazio in anticipo per informazione.
di nulla!

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

lukepet Profilo | Junior Member

Ti ringrazio, sei stato molto chiaro, solo un'altra cosa...

sto analizzando la mia applicazione per verificare se ci siano degli oggetti di cui non faccio il dispose o altro...il codice è abbastanza corposo quindi devo analizzarlo passo passo. In linea di massima mi sembra tutto ok, le form si basano tutte su un pattern che prevede in cascata il dispose del ViewModel che a sua volta richiama il Dispose della logica che a sua volta gestisce il Dispose degli oggetti dao istanziati.

Ciò che ti volevo chiedere è se sapevi consigliarmi un profiler che riesca a darmi un quadro dettagliato per individuare eventuali oggetti di cui non viene fatto il dispose. Sai indicarmi qualche tool da usare?

alx_81 Profilo | Guru

>Ciò che ti volevo chiedere è se sapevi consigliarmi un profiler
>che riesca a darmi un quadro dettagliato per individuare eventuali
>oggetti di cui non viene fatto il dispose. Sai indicarmi qualche
>tool da usare?
prova ANTS memory profiler di red-gate:
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5