Qest'anno (2008) a giugno, durante l'ultima Windows Mobility Conference di Milano, ho presentato con Alessandro Pilotti una sessione riguardante il Compact Famework 2.0, in cui analizzavamo alcuni dettagli poco conosciuti sulla parte managed dei dispositivi embeddd. Con Alessandro abbiamo deciso di pubblicare degli approfondimenti aventi per tema gli argomenti dell'intervento. In questo post analizzerò una funzionalità che permette di monitorare le performance di un'applicazione .net. Nell'esempio di questo post, prenderemo in esame un'applicazione tra quelle presenti nella directory samples nell' SDK di Windows Mobile 6.0 e più precisamente C:\Programmi\Windows Mobile 6 SDK\Samples\Common\CS\RingtoneManager. Questa applicazione contiene del codice .net abbastanza significativo e inoltre si interfaccia con delle Dll native tramite Platform/Invoke, dovendo gestire la riproduzione di suoni da file .wav o .mp3.
Preparazione
Questa funzionalità è talmente potente e precisa per quanto semplice da implementare. E' sufficiente fare il deploy dell'applcazione .net, impostare una chiave di registro, avviare l'applicazione e dopo essere usciti dalla stessa, consultare il file .stat contenente i valori di alcuni parametri estremamente significativi. Andiamo per ordine. Facciamo il build della solution e succesivamente il deploy. Connettetevi con il remote tool per l'impostazione del registry e create la chiave di registro [HKEY_LOCAL_MACHINE\Software\Microsoft\.NETCompactFramework\PerfMonitor]. Qui va creata una voce di tipo DWORD con valore 0x01 di nome Counters. Alla fine il risultato dovrà essere questo:
Poi facciamo partire l'applicazione. Questa dovrà prima trovare un pò di file di tipo .wav o .mp3, dopodichè ne selezioniamo qualcuno e lo eseguiamo:
A questo punto usciamo dall'applicazione e vediamo che è stato creato un file con nome RingToneManager.stat. Facciamo l'upload del file sul computer desktop (tramite sempre remote tools) e apriamolo con notepad (qui ne vediamo per motivi di spazio solo una parte):
I Valori statistici
Notiamo davvero un numero incredibile di voci. Proviamo ad analizzarne qualcuna.Managed Bytes Allocated, Managed Objects Allocated, Peak Bytes Allocated (native + managed)
Un alto numero di oggetti allocati non indica necessariamente un cattivo andamento dell'applicazione, comunque sia sppiamo bene che maggiore è il numero di oggetti allocati e maggiore sarà il tempo che la CPU dedicherà per l'eliminazione degli oggetti non più referenziati tramite l'attività del Garbage Collector.
Collections (Simple, Compact, Full)
Facendo riferimento ad un mio post dove spiego il funzionamento del Garbage Collector nei dispositivi embedded, con tali parametri ci possiamo rendere conto dell'attività del GC, quanto abbiamo ottimizzato la creazione di oggetti nello Heap Gestito e dove si annidano le potenziali aree di miglioramento. Per esempio in una situazione ideale no dovrebbero esserci delle full collection ed in ogni caso, qualora se ne presentassero alcune, il loro numero dovrebbe essere sempre inferiore aò numero degli altri due tipi di collection. Il rapporto tra Full Collections e Simple+Compact tende ad essere > 1 quando la memoria è sottoposta ad eccessivo stress.
GC Latency Time
E’ il totale in millisecondi del tempo di sospensione di un’applicazione dovuto alla garbage collection.
E’ direttamente collegata al Numero di Ogetti (altro parametro) e da il polso di quanto tempo impiegano le collezioni per fare il loro lavoro. E' da tenere sott’occhio quando le applicazioni sembrano inchiodarsi senza apparente motivo e riprendere successivamente.
Bytes Pitched, Number of Methods Pitched
Nel .NET Compact Framework c’è il concetto del “code pitching” e rappresenta l'azione di rimuovere il codice compilato (da MSIL a nativo) quando c’è bisogno di memoria altrimenti non disponibile. Questo causerà una successiva ricompilazione nel momento in cui ci sarà bisogno nuovamente del codice. Un parametro troppo elevato di questo tipo indica un rallentamento dell'applicazione in cui va ottimizzata la creazione di oggetti. Un’alta incidenza di pitching indica un grande utilizzo della memoria e forse che l’applicazione mantiene inutilmente vivi troppi oggetti. Possibili soluzioni possono consistere nel decrementare se possibile il numero di live objects, modificare eventualmente il device aggiungendo memorie oppure controllare se ci sono altre applicazioni che consumano troppa memoria.
Native Bytes Jitted, Number of Methods Jitted
E' il totale di codice complato in nativo. Se il numero è molto elevato, per certe aree della nostra applicazione, controllare se eventualmente non esiste un’altra successione di chiamate che fa lo stesso lavoro, con un numero minore di call
Mi riprometto di analizzare i meccanismi per migliorare le performance di applicazioni basate sul compact framework in successivi post