Archivi tag: ios

Profilare con Xcode, alla ricerca di memory leaks e non solo

Chi fa il nostro mestiere prima o poi deve affrontare dei problemi di memoria… che la si perda a causa di stress e del passare degli anni, o si scriva programmi che si affidano ad allocazione/deallocazione automatica, prima o poi tutti abbiamo problemi con questo prezioso strumento.

Il caso peggiore: memory leak in applicazione web Java

Tempo fa lavorando ad un grosso progetto web sviluppato in Java (JSF2) ci ritrovammo a metterci le mani nei capelli a causa di qualche memory leaks che rendevano per così dire “poco scalabile” la nostra applicazione. Allora usammo l’Eclipse Memory Analyzer MAT, strumento molto potente e ben fatto che permette di analizzare lo heap di qualunque applicazione Java.
Su un’applicazione web certi problemi possono essere devastanti, mentre in programmi che girano localmente su macchine provviste di parecchia RAM spesso nemmeno ci si rende conto che il nostro programma sta lentamente mangiando tutta la memoria senza rilasciarla, finché va in crash. Se però questa cosa succede di rado, e in quelle poche occasioni stavamo facendo operazioni parecchio onerose, spesso nemmeno ci facciamo caso e/o facciamo finta di niente.
Memory Leak - Comic

Memory leak?

Se non siete uno degli ultimi due personaggi della vignetta dovreste sapere a grandi linee di che si tratta, ma nel dubbio cerco di spiegarlo in poche parole: un programmatore ha sbagliato qualcosa e tra le righe di codice c’è qualche operazione che occupa memoria senza rilasciarla al termine.
Se non si programma in C raramente ci si deve preoccupare di allocare e deallocare la memoria manualmente, perché quasi tutti i linguaggi gestiscono la memoria autonomamente, allocandola ad ogni nostra dichiarazione di variabile, e facendola liberare da un garbage collector. Il GC è un processo demone che scansiona l’area di memoria dove risiedono gli oggetti e le variabili creati dal nostro programma ed elimina quelli rimasti per così dire “isolati”, ovvero che non sono più referenziati da nessuno o che sono collegati solo a oggetti non referenziati da parti “vive” dell’applicazione. In presenza di GC i memory leak sono rari perché il GC a differenza nostra non si dimentica di liberare la memoria, ma a volte proprio non ce la fa a causa di strutture mal progettate che generano riferimenti “eterni” a variabili che credevamo temporanee, e in questi casi sono dolori.

Tipico grafico di un'applicazione affetta da memory leaks, lo heap si riempe e boom

Tipico grafico di un’applicazione affetta da memory leaks

Analisi della memoria su Xcode

Sviluppando in nativo su iOS non so quanto spesso capiti di dover profilare l’applicazione alla ricerca di problemi di memoria, ma parlando di Titanium io personalmente ho dovuto preoccuparmene in più di un’occasione. Il Mac è un prodotto del demonio, però Xcode fornisce alcuni validi strumenti che in questi frangenti tornano molto utili. Vediamo come profilare un’applicazione alla ricerca di problemi di memoria e di prestazioni.

Aprendo un progetto Xcode ci si trova di fronte la finestra delle impostazioni generali, e qui dobbiamo definire le impostazioni di deploy. Generalmente la versione di iOS e il tipo di dispositivo.
IOS Profiling 1
Scegliamo la destinazione del nostro test, tra eventuali dispositivi collegati al Mac e simulatori del tipo selezionato al passo precedente. Fatto questo dobbiamo ricompilare il progetto. Considerato che stiamo per fare una profilazione, tanto vale fare il “Build for > profiling”, e al termine avviamo la profilazione con “Profile”.
IOS Profiling 2
Selezioniamo il tipo di template che più si adatta alle nostre esigenze o creiamo un template contenente tutte le metriche che ci interessano.
IOS Profiling 5
Nella schermata che si apre, quando siamo pronti, premiamo il tasto di registrazione e l’applicazione inizia a girare mandando dati agli strumenti di diagnostica scelti.
In cima all’elenco possiamo leggere istante per istante i dati generali i utilizzo della memoria, e subito sotto quali sono i tipi di oggetti che contribuiscono in maggior misura a saturare la nostra cara RAM. Il diagramma parla più di tutti, se questo inizia lentamente ad assomigliare ad una sega inclinata verso l’alto sono cazz… problemi.
IOS Profiling 6
Se certe parti del flusso del programma sono sospette e volete vedere in dettaglio come cambia l’utilizzo della memoria facendo una determinata operazione non serve segnarsi i numeri sul foglio ma possiamo usare l’utilissimo pulsante “Mark generation”. Questo serve a scattare un’istantanea di un certo punto, istantanee che possono poi essere confrontate per vedere come cambia l’utilizzo della memoria tra queste diverse “generazioni” (e quali oggetti rimangono in memoria).
Nel mio caso la memoria rimane stabile e decresce alla chiusura di alcune finestre parecchio pesanti. Se in certi punti pensate ci siano dei memory leak ma i “buchi sul tubo” sono troppo piccoli da rilevare potete prendere un trapano e allargare il buco… basta aggiungere delle immagini o in generale blob pesanti in variabili sospette per vedere meglio la RAM che se ne va.
IOS Profiling 7

Sviluppo per iOS su Titanium

Se stiamo sviluppando con Titanium probabilmente Xcode lo conosciamo molto poco, eppure nella vostra cartella del progetto (sotto build/iphone) ci dovrebbe essere un file .xcodeproj. Apritelo e vi ritroverete con il progetto Xcode che potete maneggiare e lanciare a piacimento

La cartella del progetto iOS generato da Titanium

La cartella del progetto iOS generato da Titanium

Senza scomodare Xcode

Certi strumenti sono molto potenti e possono aiutarvi molto, ma se siete dei romantici e preferite migliorare le prestazioni del vostro programma basandovi solo sull’intuito potete comunque usare la finestra di Monitoraggio delle attività di OSX. Ogni programma lanciato nel simulatore iPad/iPhone è un processo a se stante, e potete quindi tenere sempre sott’occhio la memoria che questo utilizza.

Monitorare il processo spesso è sufficiente

Monitorare il processo spesso è sufficiente

Intuito, Xcode, oscilloscopio, qualunque mezzo decidiate di usare l’importante è che ogni tanto verifichiate la stabilità e la non eccessiva onerosità dei vostri programmi. Alcuni utenti non sono molto comprensivi – giustamente – quando l’applicazione si rallenta in modo esagerato con il passare del tempo o peggio scompare dalla loro vista all’improvviso.

A mali estremi estremi rimedi: Xcode e la visualizzazione del log sui dispositivi iOS

I neofiti dello sviluppo mobile a volte rimangono sorpresi dalla varietà e dall’alto numero di errori che si manifestano quando si va a rilasciare la propria app. Generalmente su iOS grazie all’uniformità dei dispositivi non si hanno grossi problemi, ma in certe occasioni capita comunque di imprecare a lungo.

Qualche giorno fa improvvisamente la mia applicazione ha smesso di avviarsi sul dispositivo. Sul simulatore andava tutto liscio, e i certificati sembravano tutti a posto, ma dall’oggi al domani non c’era più verso di farla avviare sull’iPad. Dopo qualche ora di maledizioni alla Apple e alla sua politica nazifascista di gestione dei certificati, ho avuto la “brillante” idea di guardare i log del dispositivo, operazione tutt’altro che difficile ma che non capita di dover fare spesso.
Ebbene leggendo il log trovai l’errore immediatamente, avevo solamente scritto male la require di un modulo CommonJS, inserendo una lettera minuscola dove andava maiuscola. Nessun problema sul simulatore ma sul dispositivo questa piccola svista mandava in crash l’interprete Javascript.
Tutto bene quel che finisce bene… e velocemente.

Per chi di voi non sapesse di cosa sto parlando, vi basti sapere che Xcode nel menù Window ha una voce Devices che permette di mettere le mani su tutti i dispositivi connessi al vostro Mac, compresi i simulatori.

I dispositivi sul menù di Xcode

I dispositivi sul menù di Xcode

Dalla finestra dei dispositivi non sono solo i log di questi ultimi ad essere accessibili, ma anche le cartelle di proprietà delle varie app (container).

Log dei dispositivi e container delle applicazioni

Log dei dispositivi e container delle applicazioni

Dulcis in fundo, se vi piace mettere le mani all’interno dei file delle applicazioni usando il Finder ma navigando nelle directory dei simulatori vi capita di perdervi tra quella ventina di identificatori alfanumerici indistinguibili, ricordate che dalla schermata dei dispositivi è anche possibile ottenere l’identificatore associato a ogni simulatore, così da andare a colpo sicuro in quel marasma di caratteri e numeri. I dispositivi virtuali si trovano tutti all’interno di /Users/username/Library/Developer/CoreSimulator/Devices, da lì in avanti ci vuole la bussola.