Visualizzazione stampabile
-
Heap Size
Smanettando qua e là mi sono accorto che nalla rom stock del nostro next turbo, tramite VM Heap Size il valore impostato è 64mb. Ho letto in rete che questo valore dovrebbe essere ideale a quantitativi di ram di circa 2GB, cosa che nel nostro caso è quasi 10 volte maggiore (290 Mb).
Facendo una proporzione con quanto consigliato in rete, tale valore dovrebbe aggirarsi sui 28Mb. Qualcuno ha informazioni in merito oppure ha già effettuato dei test?
Mi vien da pensare che un valore così alto in un quantitativo così basso non si tratti di un errore ma di una scelta ben precisa in modo da migliorare la fluidità a discapito del multi tasking. Cosa ne pensate?
-
Da quanto ho capito io VM sta per [Dalvik] Virtual Machine. E' la memoria massima allocabile da ogni macchina virtuale (applicazione Android) e non ha nulla a che fare con il multitasking e/o la RAM massima. Se la rendi troppo piccola c'è il rischio che le applicazioni non partano o chiudano per memoria insufficiente. "heap" in informatica è il "mucchio" da dove si preleva la memoria dinamica, ossia allocata al momento. In altre parole mi sa tanto che sia uno di quei parametri che in assoluto non vanno toccati. Le applicazioni devono essere dimensionate a priori per non usare più di 64MB.
-
Quote:
Originariamente inviato da
Michelasso
Le applicazioni devono essere dimensionate a priori per non usare più di 64MB.
Non sulla dalvik ma in altre applicazioni mobile in JAVA dove però avevo molta più ram (sull'apparecchio girava win7), ho avuto bisogno di modificare questo settaggio a causa della mole di dati gestiti. Diciamo che è un buon valore, difficilmente lo saturerai ottenendo il fault delle applicazioni con un "java.lang.OutOfMemoryError: Java heap space". In quel caso tiralo un po' su. Analogamente se non ti servono 64MB, ma sei sicuro che ne utilizzerai molti meno allora potresti tirarlo giù a 16MB o 32MB. Ripeto sto parlando di una VM Java classica, dove:
java -Xms16m -Xmx128m my_app
lancia my_app con 16MB iniziali e 128MB massimi.
-
Quote:
Originariamente inviato da
Michelasso
Da quanto ho capito io VM sta per [Dalvik] Virtual Machine. E' la memoria massima allocabile da ogni macchina virtuale (applicazione Android) e non ha nulla a che fare con il multitasking e/o la RAM massima. Se la rendi troppo piccola c'è il rischio che le applicazioni non partano o chiudano per memoria insufficiente. "heap" in informatica è il "mucchio" da dove si preleva la memoria dinamica, ossia allocata al momento. In altre parole mi sa tanto che sia uno di quei parametri che in assoluto non vanno toccati. Le applicazioni devono essere dimensionate a priori per non usare più di 64MB.
Non la penso così, e non credo nemmeno si tratti di un parametro a cui le applicazione devono tener più di tanto conto. In parte è vero ciò che dici ovvero dovrebbe trattarsi di una speci di buffer di una certa dimensione il quale se sovrariempito genera delle operazioni I/O eliminando i dati vecchi con i nuovi. Ciò occupa CPU e può generare consumi maggiori e/o rallentamenti.
Quote:
Originariamente inviato da
Ikon
Non sulla dalvik ma in altre applicazioni mobile in JAVA dove però avevo molta più ram (sull'apparecchio girava win7), ho avuto bisogno di modificare questo settaggio a causa della mole di dati gestiti. Diciamo che è un buon valore, difficilmente lo saturerai ottenendo il fault delle applicazioni con un "java.lang.OutOfMemoryError: Java heap space". In quel caso tiralo un po' su. Analogamente se non ti servono 64MB, ma sei sicuro che ne utilizzerai molti meno allora potresti tirarlo giù a 16MB o 32MB. Ripeto sto parlando di una VM Java classica, dove:
java -Xms16m -Xmx128m my_app
lancia my_app con 16MB iniziali e 128MB massimi.
Ho trovato in merito questi riferimenti in rete che indicano dimensionamenti della porzione di questo "buffer" assegnata ad ogni app:
Gingerbread a default → 24m heap
512mb ram → 40-48m heap
1GB → 64mb
noi ne abbiamo 290, ho fatto una proporzione ed ho impostato 28m e vediamo che succede.
Cmq se è troppo piccolo può accadere quello che dice Michelasso, se è troppo grande siccome vengono date 64m a tutte le applicazioni, un multitasking di più di 4-5 applicazioni dovrebbe genera rallentamenti importanti, soprattutto nell'I/O. Ora se apro 2-4-6 applicazioni di cui una è sempre Antutu e lancio un test i valori potrebbero essere indicatori di un simile comportamento?
@michelasso: sai per caso quanta ram occupa Go Launcher persistente nel sistema?
EDIT: una possibile definizione di heat: un’area di memoria dinamica allocata per permettere alle applicazioni in esecuzione di poggiarci sopra i loro dati, appunto dinamicamente. In questo modo i dati delle applicazioni vengono richiamati molto velocemente, proprio perché l’accesso alla RAM è molto più veloce che accedere alle memorie flash. Quindi in linea teorica più è grande il valore della VM Heap Size e più il sistema sarà veloce perché tutte le applicazioni lavorano in RAM, ma ciò aumenterà anche la durata della batteria, perché l’I/O su memoria esterna sarà molto più ridotto … In altre parole VM Heap Size è una sorta di cache per le applicazioni.
EDIT2: il test antutu col solo benchmarck aperto non riporta differenze sostanziali modificando il valore da 64 a 28. I test fatti in performance/sio danno valori sempre simili tra loro anche per quanto concerne il Database I/O.
EDIT3: con 5 applicazioni attive nel task manager antutu mi ha dato addirittura il miglior test di sempre 2068 ma non nei valori significativi... solo grazie ai bench sulla sd
-
Quote:
Originariamente inviato da
samurri
Non la penso così, e non credo nemmeno si tratti di un parametro a cui le applicazione devono tener più di tanto conto. In parte è vero ciò che dici ovvero dovrebbe trattarsi di una speci di buffer di una certa dimensione il quale se sovrariempito genera delle operazioni I/O eliminando i dati vecchi con i nuovi. Ciò occupa CPU e può generare consumi maggiori e/o rallentamenti.
Ho trovato in merito questi riferimenti in rete che indicano dimensionamenti della porzione di questo "buffer" assegnata ad ogni app:
Gingerbread a default → 24m heap
512mb ram → 40-48m heap
1GB → 64mb
Non so dove tu abbia trovato quei valori, ma Gingerbread, giudicando dal /system/build.prop del nostro telefono usa un default di 64MB: dalvik.vm.heapsize=64m
Nè io, né sicuramente Zack abbiamo toccato quella linea, quindi, al solito, attento alle fesserie che trovi in giro nel mondo Android.
Poi bisogna vedere come funziona l'heap in Java/Dalvik. Ikon sicuramente ne saprà più di me. Se quei 64MB o quanti sono vengono allocati subito per ogni applicazione/macchina virtuale (mi parrebbe strano, ma con Android tutto è possibile) allora si, è chiaro che aumentandone il valore avresti meno applicazioni residenti in memoria allo stesso tempo. Che visto come gira nel Next Turbo è anche possibile se non probabile a dire il vero. Alzandolo in questo caso faresti peggio, perché riduci la memoria disponibile per le seconde applicazioni.
Diminuendolo che capita? Se le applicazioni vanno in fault, come dice Ikon, sei fregato. Semplicemente non puoi diminuirlo. Se invece le Dalvik Machine implementano un meccanismo per togliere degli oggetti liberando spazio per altri, dopo avere fatto girare un garbage collection allora è possibile che tutte le applicazioni girino sempre ma con performance ridotte. Cosa che, di nuovo, non so.
Aggiungi il fatto che Android ha la sua gestione personale di memoria la quale ammazza le applicazioni attive per far spazio in memoria. In altre parole un bordello immane. Che puoi complicare ulteriormente attivando la swap e quindi la Virtual Memory (quello che VM è sempre stato a casa mia), che non si capisce come interagisca con tutto quanto scritto sopra e quindi apposta ti dicevo che se vuoi abilitarla devi capire e trovare quali sono i parametri migliori. Ma non a tentativi, con una deduzione logica dati gli elementi che ci sono in gioco.
Per quanto riguarda quanta memoria usi GO Launcher non lo so. Sinceramente non è una questione che mi pongo, tanto il multitasking in questo telefono non è che serva granché, mal che vada le applicazioni vengono terminate e se mi servono di nuovo le faccio ripartire.
Quote:
Originariamente inviato da
Ikon
Non sulla dalvik ma in altre applicazioni mobile in JAVA dove però avevo molta più ram (sull'apparecchio girava win7), ho avuto bisogno di modificare questo settaggio a causa della mole di dati gestiti. Diciamo che è un buon valore, difficilmente lo saturerai ottenendo il fault delle applicazioni con un "java.lang.OutOfMemoryError: Java heap space". In quel caso tiralo un po' su. Analogamente se non ti servono 64MB, ma sei sicuro che ne utilizzerai molti meno allora potresti tirarlo giù a 16MB o 32MB. Ripeto sto parlando di una VM Java classica, dove:
java -Xms16m -Xmx128m my_app
lancia my_app con 16MB iniziali e 128MB massimi.
E' possibile che Dalvik in Android usi un valore minimo di zero MB? Sul dimensionamento, poiché non è possibile modificarlo dall'utente normale (serve root) son propenso a credere che quella dimensione debba rientrare nelle specifiche di sviluppo della applicazioni. Ma come avrai letto non è la mia materia.
PS: Ho fatto una prova, e ho messo l'heap a 8MB. Ovviamente per testarlo nel caso estremo. Risultato? Bootloop continuo. Crash delle applicazioni di sistema. Samurri, lascia perdere. Come ho detto è uno di quei valori dai quali è meglio starci distanti.
-
Il problema è che dai test che ho fatto non è cambiato nulla e posso ipotizzare per 2 ragioni: non ho usato gli strumenti giusti per valutare la differenza oppure non ho usato un mix tra valore heap e garbage collection adeguato. Chiaro che questa questione potrebbe essere lunghissima e non generare parametri standard individuabili come possibili ottimizzazioni perchè è legata all'uso che se ne fa del telefono. Il valore 64mb è il massimo impostabile e "dovrebbe" essere il più conservativo sul lato batteria e forse ha dietro anche una sua logica, ovvero su un terminale così limitato come il nostro e con una batteria così piccola, quante applicazioni possono girare simultaneamente? poche, e che senso ha averne fluide 10 invece di 5 se 10 magari uccidono la batteria nel solo istante che le hai tutte in funzione? meglio poche fluide e che risparmiano la batteria, al massimo scatta un rallentamento a causa delle operazioni I/O di svuotamento riempimento.
Una prova sarebbe vedere che succede se mpostassi il valore heap ad 1: in linea di principio potrei non ottenere errori di memoria insuff, ma solo tempi disumani di caricamento di un'applicazione ma devo fare un backup prima o rischio di dover ripristinare con odin.
Esiste un task manager per android simile a quello di windows per valutare il carico sulla cpu e sulla ram, magari da poter controllare accanto all'indicazione della batteria?
@miché: hai usato vm heap size per impostare il valore a 8?
-
Ho usato ROM Toolbox Pro il quale modifica il build.prop che è l'unico posto dove va settato quel valore visto che deve valere per tutti. Poi via "adb shell" l'ho ripristinato a 64m quando l'UI di Android allegramente se ne andava in bootloop. Ovviamente ho fatto un reboot fisico del telefono dopo il ripristino al valore standard.
In ogni caso il discorso è semplice: questi telefoni sono progettati per telefonare, navigare in Internet e far girare una applicazione alla volta più i widget. Nulla di che, e quel lavoro lo fa anche bene. Se poi volete prestazioni più veloci e/o una batteria più capiente allora comprate un telefono di fascia alta. Io l'unico tweak che veramente ho visto produrre qualche risultato è il setting del minfree per la memoria. Quello che stabilisce quando Android chiude le applicazioni. A me, pare, che il telefono laggi un po' meno. Forse perché avendo meno applicazioni attive (vengono chiuse) la CPU ha meno lavoro da fare...
-
Mi sono documentato un attimino. Ho scoperto alcune cose carine. Magari sarò banale, comunque cito i riferimenti perchè possono tornare utile a qualcuno che legge il thread. Potrei dire anche qualcosa di scontato ai più, comunque se un non addetto ai lavori legge il post vorrei che riesca a capire lo stesso.
Quote:
Dalvik was originally written by Dan Bornstein
(cit. Dalvik (software) - Wikipedia, the free encyclopedia)
Quote:
The Dalvik heap is preloaded with classes and data by zygote (loading over 1900 classes as of Android version 2.2). When zygote forks to start an android application, the new application gets a copy-on-write mapping of this heap. As Dan Borstein says below, this helps with memory reduction as well as application startup time.
Dalvik, like virtual machines for many other languages, does garbage collection on the heap. There appears to be a separate thread (called the HeapWorker) in each VM process that performs the garbage collection actions. (See toolbox ps -t)
Dan Borstein said this about heap sharing:
"It's used in Android to amortize the RAM footprint of the large amount of effectively-read-only data (technically writable but rarely actually written) associated with common library classes across all active VM processes. 1000+ classes get preloaded by the system at boot time, and each class consumes at least a little heap for itself, including often pointing off to a constellation of other objects. The heap created by the preloading process gets shared copy-on-write with each spawned VM process (but again doesn't in practice get written much). This saves hundreds of kB of dirty unpageable RAM per process and also helps speed up process startup."
(cit. Android Memory Usage - eLinux.org)
A questo punto chiarirei anche il concetto di heap, perchè non so voi ma io sono più di 5 anni che l'ho studiato e non mi ricordo "una beata m****a"!
Quote:
Heap (or free store), an area of memory used for dynamic memory allocation.
(cit. Heap - Wikipedia, the free encyclopedia)
Senza farci troppe seghe mentali su segmentazione, virtualizzazione, paginazione e compagnia cantando (perchè sennò mi ritirano la laurea), dividerei la memoria (virtuale, cioè come la vede una applicazione) in stack ed heap. Se pensiamo che lo stack cresca dal basso verso l'alto (con strategia LIFO), l'heap cresce dall'alto al basso (la strategia di allocazione non è lineare come per lo stack).
Mentre lo stack accoglie valori come contenuto dei registri, indirizzi, parametri e variabili automatiche per permettere chiamata e ritorno delle funzioni, l'heap accoglie le variabili dinamiche. Considerando che stiamo parlando di JAVA allora possiamo dire che l'heap accoglie "tutta" la memoria impiegata all'interno di un processo.
Per la Dalvik mi sembra di capire che allo startup del sistema Zygote carichi tutte le librerie (un botto) nello heap. Quando è tutto pronto, i processi VM si ritrovano a condividere lo stesso heap. Per evitare problemi è usata banalmente una tecnica di copy-on-write: in sostanza l'heap viene copiato e le modifiche vengono effettuate sempre sulla copia, però poi vengono riportate consistentemente sull'originale al fine di evitare concorrenza.
Perciò da questo ne deduco che:
- la dimensione minima dello heap deve essere almeno pari a tutta la fuffa che Zygote carica al boot
- la dimensione massima dello heap è al max quella della memoria fisica
- una buona dimensione dello heap della Dalvik non dipende dall'applicazione come nella VM Java classica
Se mettete un valore spropositato tipo 290Mb cosa vi succede?
-
dunque io uso VM heap size ed il massimo impostabile è 64mb e a default è 64mb. Ho provato 28mb senza notare alcunchè, Michelasso ha impostato 8 mb e ha avuto continui bootloop.
In rete ho trovato che il default di gingerbread è 24, di honeycomb è 48, il resto l'ho scritto sopra
-
Ok ho trovato qualcosa di davvero interessante:
Quote:
It’s not “virtual memory,” it’s real memory. This setting is simply the maximum amount of heap space (read: memory) a single instance of the Dalvik VM (read: application) can obtain.
The only scenario where it would be beneficial to increase the maximum heap size would be if you have an application that is very close to using up all of its available heap space, which would force it to run garbage collection frequently, which would use up CPU cycles. It is possible that lowering the maximum heap size could be beneficial in that it might prevent an application from obtaining more memory than it needs (by forcing it to garbage collect sooner), but that all depends on how the Dalvik VM is implemented and is really beyond my knowledge.
It is the memory allocated to the dalvik virtual machine increasing it will use more memory if the apk calls for it and decreasing will use less,but go into garbage quicker thus making the apk perform less efficiently. This has to do with reading java code increasing the dalvik.vm will probably make no noticeable differences.
Actually, I would suggest bumping up VM heap space to maximum because it reduces GC runs to only when strictly necessary – and *any* GC algorithm is costly. In short, at the expense of little memory (that you wouldn’t be using anyway) you get applications that perform smoother plus lower battery usage.
(cit. What is Dalvik VM Heapsize? benefits and downfalls? « butterflydroid)
In sostanza:
- ogni istanza della Dalvik si ciuccia N = dalvik.vm.heapsize megabyte di memoria. Quindi più istanze ci sono più swap-in/swap-out ci sono in caso di saturazione della memoria.
- Tuttavia avere un heap più grosso permette di diminuire il numero di esecuzioni del Garbage Collector (quando l'heap è in saturazione).
Perfetto vai... ci sono arrivato! Adesso sono allineato a quello che dicevate. Ragionare ad alta voce anche sui forum aiuta :P
-
Quote:
Originariamente inviato da
samurri
dunque io uso VM heap size ed il massimo impostabile è 64mb e a default è 64mb. Ho provato 28mb senza notare alcunchè, Michelasso ha impostato 8 mb e ha avuto continui bootloop.
In rete ho trovato che il default di gingerbread è 24, di honeycomb è 48, il resto l'ho scritto sopra
I suoi bootloop sono dovuti al fatto che Zygote non riesce a caricarci tutta la roba allo startup...
-
Quote:
... i processi partono e questi al posto di avere un loro heap usano tutte lo stesso heap comune.
questa non l'ho capita
-
Quote:
Originariamente inviato da
samurri
questa non l'ho capita
hai ragione! magari se rileggessi quello che scrivo prima di premere invia... aspetta vado a editare!
-
Qui si capisce meglio la questione Zygote:
Quote:
Zygote enables multiple Dalvik instances to share memory to limit the memory burden of each running concurrently. As the name implies, Zygote's purpose is to provide a preloaded Android process ready for a new application, without incurring the delay of starting from scratch. During the initialization of the Zygote, core classes are preloaded into memory to allow even faster application startup. Since each Zygote uses copy-on-write for shared memory space, much of the memory for each application is reused and thereby places a lighter burden on the limited resources of the device. This only works because these core classes are mostly read-only and will rarely require more than one version for all applications. Compared to a typical Java virtual machine, this is quite an improvement in performance and memory efficiency since they do not exhibit this type of memory sharing between instances. Once the classes are loaded, the Dalvik VM itself is then initialized and is ready to run Dalvik bytecode from a dex file. Once the Zygote has been inhabited by a new application, another Zygote is forked to wait on a socket for the next application to be launched.
(cit. Android Dalvik Virtual Machine)
Dove:
Quote:
Every Android application runs in its own process, with its own instance of the Dalvik virtual machine.
(cit. http://developer.android.com/about/versions/index.html)
Abbiamo tutti gli elementi per valutare la questione "numero di istanze della VM", ci mancano elementi sulla frequenza del garbage collector. Se troviamo anche quelli possiamo tirare giù qualche formula!
-
Quote:
So garbage collection can be triggered when an allocation fails, when an OutOfMemoryError is about to be triggered, when the size of the heap hits some soft limit, and when a GC was explicitly requested. Each of these causes has its own specification indicating whether the GC is a partial GC (only free from active heap), a concurrent GC (do most of the object marking while other threads running), and whether it is a preserving GC (keep soft references).
Your typical GC is triggered by a soft allocation limit, only freeing on the active heap, concurrent, and preserving. On the other extreme the GC triggered before an OutOfMemoryException is full, synchronous, and non-preserving.
(cit. Android Development: How does garbage collection work in Android Dalvik? - Quora)
Dopo questo ho trovato delle slides grandiose: http://dubroy.com/memory_management_...droid_apps.pdf
Questo invece sono gli appunti presi da qualcuno durante la presentazione delle slides di prima: http://static.googleusercontent.com/...Management.pdf
Da questo si capisce che non possiamo intuire se stiamo in una situazione di garbage collecting frequente semplicemente analizzando le occupazioni di memoria dei processi. Ciò significa che dobbiamo analizzare i log. Dall'analisi dei log siamo in grado di recuperare gli eventi di esecuzione de GC relativi a:
- Heap quasi pieno (pieno oltre una soglia)
- Heap pieno (ovvero prima di un potenziale lancio dell'eccezione java.lang.OutOfMemoryError)
A questo punto fatto N il numero di processi attivi, data M la dimensione della memoria e calcolato attraverso il log H, numero di esecuzioni del GC nell'unità di tempo avvenuti a fronte di eventi relativi al riempimento dell'heap, si avrà:
s ~ M/(N*H)
dove s è la dimensione ottima dell'heap.
Quello che si può fare è analizzare comportamenti medi (in base all'utilizzo tipico del singolo utente) relativi a N ed H. Questo si può fare parsando i log in background con una applicazione ad-hoc che poi magari calcola "s" (considerando analisi di lungo periodo) e modifica dalvik.vm.heapsize.
Tuttavia la formula che ho determinato non è una formula: dice solo che la dimensione ottima dell'heap è direttamente proporzionale alla memoria disponibile e inversamente proporzionale al prodotto tra il numero di processi attivi e il numero di esecuzioni del garbage collector nell'unità di tempo.
Inoltre in realtà H è funzione di "s". Perciò se H(s) non si può approssimare bene con una funzione lineare (e a meno di qualche costante) la formula non sarà calcolabile in forma chiusa. Quindi andrà anche definito un metodo matematico per il calcolo della soluzione.
Se facciamo l'applicazione, secondo me realizziamo qualcosa di veramente figo :cool:
-
bravo, mi sono avvicinato a questa faccenda per capire certi strani comportamenti di questo telefono e la questione heap mi ha subito colpito. Dalla tua ricerca ho trovato molte conferme ma non riesco per poca dimestichezza a capacitarmi di quante volte nell'uso normale si possono raggiungere queste situazioni di pieno riempimento.
questo è importante perché rende l'idea di quanto un'ottimizzazione di questo genere possa portare dei benefici a molti.
Inviato dal mio GT-S5570I usando Androidiani App
-
Secondo me una idea ce la possiamo fare analizzando i log come indicato nelle slides. Se esistono applicazioni che frequentemente generano attivazioni del GC allora può avere un senso. Quanto ognuno dei fattori M, K, N e H sia veramente positivo/negativo in termini di peso sulle prestazioni complessive determina vari parametri adimensionali che complicano la formula e fanno sì che alla fine:
s = f(M, K, N, H)
approssimi molto bene la dimensione ottima dell'heap.
-
Quote:
Originariamente inviato da
samurri
dunque io uso VM heap size ed il massimo impostabile è 64mb e a default è 64mb. Ho provato 28mb senza notare alcunchè, Michelasso ha impostato 8 mb e ha avuto continui bootloop.
In rete ho trovato che il default di gingerbread è 24, di honeycomb è 48, il resto l'ho scritto sopra
Ti ho già risposto che il default della nostra ROM, che è standard Gingerbread, è 64MB. A meno che non intendessero la dimensione minima dell'heap a seconda della versione di Android. Li il discorso cambia perché come abbiamo visto se l'heap è troppo piccolo Zygote non riesce a caricare tutte le classi. E naturalmente versioni superiori di Android hanno più classi di maggiore dimensione. Anche se il doppio mi pare francamente troppo, ma è pure vero che Honeycomb è solo per i tablet (che si spera abbiano più memoria!)
Quote:
Originariamente inviato da
Ikon
In sostanza:
- ogni istanza della Dalvik si ciuccia N = dalvik.vm.heapsize megabyte di memoria. Quindi più istanze ci sono più swap-in/swap-out ci sono in caso di saturazione della memoria.
- Tuttavia avere un heap più grosso permette di diminuire il numero di esecuzioni del Garbage Collector (quando l'heap è in saturazione).
Perfetto vai... ci sono arrivato! Adesso sono allineato a quello che dicevate. Ragionare ad alta voce anche sui forum aiuta :P
Aumentare l'heap size permette di ridurre il numero di esecuzioni del GC se l'uso del heap da parte delle applicazioni è vicino alla saturazione, ma al tempo stesso può ridurre in numero max di applicazioni attive concorrenti. Quindi invece di eseguire il GC ti ritrovi a dover ricaricare tutta l'applicazione, perché questa viene uccisa dall'application manager.
Boh.. Non mi sembra che si discosti molto da quanto dicevo. Zygote a parte, che non sapevo che contenesse tutte le classi Android. La cosa che non ho capito e se questo heap viene preallocato dal kernel per ogni applicazione. Se fosse così un heap troppo grande sarebbe un disastro. Quello troppo piccolo già lo è come abbiamo visto.
Quote:
Originariamente inviato da
samurri
bravo, mi sono avvicinato a questa faccenda per capire certi strani comportamenti di questo telefono e la questione heap mi ha subito colpito. Dalla tua ricerca ho trovato molte conferme ma non riesco per poca dimestichezza a capacitarmi di quante volte nell'uso normale si possono raggiungere queste situazioni di pieno riempimento.
questo è importante perché rende l'idea di quanto un'ottimizzazione di questo genere possa portare dei benefici a molti.
Questa invece non l'ho capita. Quali benefici? Meglio avere un heap più piccolo che permetta di avere più applicazioni in memoria ma che esegue più spesso il garbage collector, se mai viene eseguito, oppure uno più grande con più applicazioni che devono essere fatte ripartire perché vengono uccise più spesso dall'Application Manager? Oppure la via di mezzo come effettivamente sembra che abbiamo?
E' come per il discorso dell'applicazione ipotizzata da Ikon. Tale applicazione avrebbe poco senso in un telefono general purpose. Quelle considerazioni si fanno per il tuning di server che si sanno eseguire solo una mansione/servizio/applicazione e quindi possono beneficiare di particolari settaggi perché il loro tipo di uso sarà più o meno costante nel tempo. Ma dato l'utilizzo di un giorno del telefono e calcolando su quello l'heap size per il prossimo reboot, può capitare e capiterà sicuramente che l'utente faccia la volta dopo un uso totalmente diverso. Come del resto l'uso può cambiare di ora in ora.
Bah. In ogni caso ho appena fatto la prova del 9. Ho testato con 24MB e 124MB (valore max consentito in ROM Tollbox Pro). A mio avviso non cambia una pippa. Ho aperto 6 applicazioni e sono passato da una all'altra via tenendo premuto Home. Google Play non viene mai ucciso, si vede perché si riapre subito con già tutte le icone caricate, Whatsapp torna dov'era ma ci mette un po' ad aprirsi, Agenda lo stesso, facendo pensare che le applicazioni in realtà fossero terminate e tornino al punto dove erano state lasciate (come dovrebbero), Freespace ci mette un po' ma imbroglia, se ho aperto un grafico e mi sposto su di un altro, poi riaprendolo torna al primo grafico. Che non dovrebbe succedere, a meno che appunto l'applicazione non fosse stata terminata. Stesso identico comportamento per tutte con i due valori di heap space menzionati. Ah, GO Task Manager Ex riporta sempre la stessa memoria consumata in entrambi i casi (cioè, tre casi: lo stesso con l'heap di 64MB).
Credo che il discorso sia semplice: Zygote ha un heap grande e quindi le applicazioni consumano di solito meno. Così non si notano differenze. Con L'heap che a questo punto viene a sua volta allocato dinamicamente dalla gestione della memoria virtuale del kernel (paging) e perciò anche sovradimensionato non darà mai problemi reali di memoria (a livello di RAM allocata dal kernel).
-
Non ho capito io questa volta il tuo intervento hai rifatto i test già fatti e ridetto le stesse cose. bisogna vedere i log per capire l'effetto e l'efficacia di questa modifica e, alla luce di quanto detto forse e dico forse, 64MB di default è troppo. quindi l'heap size è unico? 64mb ad esempio è fisso e viene dinamicamente occupato da n applicazioni? devo rivedere alcune cose che sono state postate
Inviato dal mio GT-S5570I usando Androidiani App
-
Quote:
Originariamente inviato da
samurri
Non ho capito io questa volta il tuo intervento hai rifatto i test già fatti e ridetto le stesse cose. bisogna vedere i log per capire l'effetto e l'efficacia di questa modifica e, alla luce di quanto detto forse e dico forse, 64MB di default è troppo. quindi l'heap size è unico? 64mb ad esempio è fisso e viene dinamicamente occupato da n applicazioni? devo rivedere alcune cose che sono state postate
Inviato dal mio GT-S5570I usando
Androidiani App
Quali test già fatti? Hai fatto il test cambiando l'heap size a 24MB e 124MB? O comunque a due valori estremi? E perché 64MB sarebbe troppo? Se è come dico io, e altrimenti non dovrebbe essere, l'heap size potrebbe avere anche la dimensione di tutta la RAM che non cambia un tubo. Perchè Dalvik introduce un secondo livello della gestione della memoria. Sotto ci sta ovviamente la gestione della memoria paginata del kernel, la stessa che viene usata dalla swap, ma che è utilizzata anche se la swap non esiste.
In pratica il discorso è semplice, ed è una delle prime cose che si insegnano a informatica: il kernel alloca pagine di RAM solo quando queste sono richieste. Quando un apk parte non carica tutte le sue classi in memoria. Carica solo quelle che vengono richieste, quando vengono richieste. Quando richiede una sua classe, che avrà bisogno di un certo spazio in RAM, il kernel, che ha già mappato queste classi in uno spazio di memoria virtuale si preoccupa di allocare le pagine in RAM necessarie, e caricarle dal supporto di I/O, sia questo una memoria flash, un hard disk o anche un lettore di schede (gli ultimi 2 non ci sono in Android, ma se ci fossero il concetto sarebbe quello). Questo se viene generato un fault perché la classe, o meglio il codice, in RAM non esiste.
Se invece l'apk ha bisogno di classi, oggetti del Zygote, li accede normalmente perché sono già nell'heap di Zygote. Dopo averli però mappati nello spazio di memoria virtuale dell'apk. Ma allocati come copy-on-write. Che significa allocare memoria come copy-on-write? Che il kernel, fintantoché quelle pagine di memoria condivisa vengono accedute solo in lettura, continuerà ad utilizzare le stesse pagine RAM per quelle classi di Zygote. Se per qualche motivo c'è la necessità di eseguire un write, e quindi sporcare tali pagine (modifica dei dati), il kernel prima di eseguire il write farà un clone della pagina RAM che l'apk deve accedere, e rimapperà lo spazio di memoria virtuale dell'apk per scrivere in quella pagina e non più in quella condivisa da Zygote.
In ogni caso cosa comporta avere una dimensione piccola dell'heap? Che alcuni apk possono allocare e rilasciare memoria di continuo. Questo processo porta a una frammentazione dell'heap che a un certo punto dovrà essere "ricompattato", "riordinato", eseguendo il garbage collector. Il quale altro non fa che prendere tutti i segmenti di memoria che sono stati rilasciati (marcati come liberi) e unirli cercando di ottenere segmenti continui più grandi per far spazio a una nuova richiesta di memoria da parte dell'apk (qui siamo a livello Dalvik, non a livello kernel. Ogni garbage collector ha i suoi algoritmi per essere più o meno ottimizzato e di sicuro non mi addentrerò in quello di Dalvik di Android, perché sinceramente questa ciofeca con macchine virtuali potevano fare anche e meno di implementarla). Quando a furia di allocare e rilasciare non ci sarà più un segmento grande abbastanza per allocare lo spazio richiesto, parte il garbage collector. Se anche dopo il GC a causa di troppa frammentazione tale segmento non esiste l'apk va in fault per mancanza di memoria. Il che significa che un heap size troppo piccolo non è bello. Anche se tale situazione non dovesse mai verificarsi si avrebbero comunque dei GC più o meno periodici.
Dimensionando quindi un heap size più grande riduci il numero di possibili esecuzioni del GC e soprattutto di eventuali fault. Ma se gli apk sono piccole applicazioni dal bisogno modesto di risorse, che una volta allocata un'area nell'heap quella si tengono, la dimensione dell'heap size, purché adeguata per tenere l'heap di Zygote, diventa del tutto ininfluente. Il che sembra essere appunto il caso della maggioranza delle applicazioni che utilizziamo. Forse i giochi e i web browser possono dare più problemi di prestazioni, in quanto trattano maggiori moli di dati in scrittura. Un maggior valore di default per l'heap size potrebbe aiutare? Non lo so. Potrebbe esserci anche la possibilità che le applicazioni possano ignorare quel valore e stabilire loro stesse la dimensione dell'heap. Ma per la maggioranza delle applicazioni mi pare che il problema non si ponga. Dando un'occhiata veloce alla memoria occupata da queste si vede che al massimo consumano sui 20MB, quindi ben al di sotto dei 64MB di default del nostro telefono, ma anche dei 24MB che forse sono il valore minimo per Zygote.
-
No l'heap è lo stesso non viene preallocato per ogni processo. Viene allocato solo all'avvio. Poi è tutto condiviso tra le istanze dalvik, però alcune parti vengono realmente replicate per via del copy-on-write.
Quindi tu dici che una applicazione che monitora la cosa non avrebbe senso? Ci si guadagnerebbe troppo poco? Io pensavo di tenere il cell costantemente monitorato e dimensionare l'heap in base all'utilizzo medio su una finestra temporale grossa tipo 1 mese... L'unico vantaggio, ma non so di che ordine di grandezza, sarebbe in termini di consumo energetico...
-
Quote:
Originariamente inviato da
Ikon
No l'heap è lo stesso non viene preallocato per ogni processo. Viene allocato solo all'avvio. Poi è tutto condiviso tra le istanze dalvik, però alcune parti vengono realmente replicate per via del copy-on-write.
Quindi tu dici che una applicazione che monitora la cosa non avrebbe senso? Ci si guadagnerebbe troppo poco? Io pensavo di tenere il cell costantemente monitorato e dimensionare l'heap in base all'utilizzo medio su una finestra temporale grossa tipo 1 mese... L'unico vantaggio, ma non so di che ordine di grandezza, sarebbe in termini di consumo energetico...
Scusa, ma anche le applicazioni avranno bisogno del loro heap, o no? Mica usano solo le classi del Zygote. Ogni apk definisce le sue classi in Java. Almeno credo, come professo da tempo io Java lo detesto. :D
E' il problema della sfera di cristallo. Valgono le stesse considerazioni che valgono per gli algoritmi di paging. Stabilito un algoritmo è sempre possibile fare una applicazione che quell'algoritmo lo fa impazzire. Certo ci sono le considerazioni statistiche. Ma presuppongono un uso "tipico" del sistema. Se hai un server Oracle puoi fare determinati tuning ottenendo dei vantaggi, ma se quei tuning li applichi a un server general purpose ottieni l'effetto contrario. E la fregatura sta nel "general". Un giorno fanno una cosa (magari proprio si atteggiano a server Oracle per una giornata), l'altro calcolo scientifico. Nel caso dei smartphone, un giorno chiami e basta, l'altro fai solo web browsing, un altro giochi. Ti salterebbe fuori un valore medio che alla fine mi sa tanto che sarebbe lo stesso di quello che già c'è. Non è che chi sviluppa gli OS non faccia la sua analisi delle perfomance.
In ogni caso sarebbe solo tempo perso per altri motivi: test empirici provano che posizionare quel valore agli estremi sembra del tutto indifferente. A meno che non sia sottodimensionato il che causa fault al Zygote o a applicazioni di sistema in generale (avrei dovuto controllare meglio. Ce n'era più di una che dava FAILURE).
Io personalmente nei server dai tuning, e specialmente da chi i tuning li professa, sono sempre stato distante. Uno di quelli che chiamava più spesso con problemi al server Domino era ovviamente il fesso che andava a toccare tutti i parametri di sistema/tuning, nella speranza di migliorare il sistema. Poi regolarmente questo andava in crash (perché Domino è un cesso). Come su tutto vale sempre la solita regola d'oro: il sistema non è performante? Compra un HW più potente. Che ne esce uno ogni mese o quasi. Ecco, problemi di tuning risolti. rotfl
-
Si in linea di massima hai ragione... è inutile starsela a menare. Come dice Bersani: "Oh ragassi, se hai gli occhi a mandorla non è che piangi l'orzata...". Perciò ci sta che qualcosina la riesci a recuperare, ma alla fine non hai guadagnato così tanto da giustificare il lavoro.
Per quanto riguarda l'heap io avevo capito che era condiviso, ma è tutto abbastanza fumoso...