l’avreste mai detto che…

java_memory Salve, eccomi qui… non credo che abbia molto pubblico, e chissà quando mi troverete nell’infinito di Internet, ci saranno milioni di blog sulla programmazione, quindi passerà un bel po di tempo prima che mi scoviate…spero nella bontà di gooogle che possa indicizzarmi presto come si deve. Nell’attesa volevo parlare di una cosa che ho letto poco tempo fa, che mi ha fatto notare ancora una volta quanto è potente Java. Vi sottopongo la seguente domanda: "Quale linguaggio di programmazione tra C++ e Java risulta più veloce nell’allocazione della memoria?". Non ci crederete ma la risposta è Java !!! Nelle moderne JVM l’allocazione della memoria risulta essere molto veloce rispetto alle classiche operazioni di malloc() usate in C++. Più precisamente in Java sono richieste 10 istruzioni macchina (approssimativamente) per allocare memoria per la più comune delle allocazioni
new Object() mentre in C++ sono richieste una media di 60-100 istruzioni macchina. Ovviamente non c’è trucco non c’è inganno, nel senso che quelle ottime performance si devono alla gestione della memoria da parte della JVM. La JVM utilizza un garbage collector generazionale, cioè la memoria (l’heap) viene suddiviso in spazi generazionale, uno detto young e l’altro old. In questi due spazi vengono mantenuti i riferimenti agli oggetti presenti nella memoria la cui vita risulta essere rispettivamente corta o lunga, misurata in operazioni di garbage collector. Più precisamente gli oggetti che hanno superato un certo periodo di tempo vengono trasferiti dallo spazio young a quello old e vengono etichettati come long lived. Ad ogni operazioni del garbage collector gli oggetti più vecchi vengono eliminati dalla memoria e quindi viene liberato lo spazio per i nuovi. Sebbene questo è il funzionamento di base della gestione della memoria di Java, la pratica è leggermente diversa, la JVM offre 3 young-generational collectors, che sono serial copying, parallel copying, e parallel scavenge. Tutti e tre hanno la caratteristica di dividere lo spazio di memoria a metà e utilizzano sempre una metà alla volta fino a che non viene riempita. L’allocatore della memoria soddisfa le richieste di allocazione restituendo i primi N bytes della portione di memoria libera, spostando un puntatore che separa le due parti "utilizzata" da "libera". In definitiva, l’allocazione di memoria consiste nel controllare se esiste dello spazio disponibile nell’heap e restituire un puntatore ad esso, senza effettuare alcuna ricerca o adottare alcuna politica di gestione dello spazio. C++ offre al programmatore la scelta di adottare l’allocazione di memoria sia sullo heap che sullo stack. Il fatto di utilizzare lo stack per allocare la memoria implica un aumento delle prestazioni, sia durante l’allocazione che è economica in termini prestazionali e sia durante la deallocazione che costa 0, inoltre i linguaggi implementano una attenta gestione della politica di demarcazione degli oggetti, riducendo così il rischio di non liberare lo spazio al termine della vita di un oggetto. Un altro vantaggio dello stack è dato dal fatto di essere molto più cache-friendly, e questo indica un aumento delle prestazioni in termini di diminuzione dei cache miss, per i quali, sui moderni processori, si hanno dei ritardi significativi. Java non consente al programmatore di allocare spazio direttamente sullo stack, ma questo non è un grosso vincolo, dal momento che la JVM va ad allocare all’occorrenza spazio sullo stack che permette così di aumentare di molto le prestazioni. Le JVMs utilizzano una tecnica chiamata escape analysis la quale permette di stabilire che alcuni oggetti per tutta la durata del loro lifetime, rimarranno confinati all’interno di un singolo thread e pemette di mappare questo lifetime con il lifetime di uno stack-frame. Queste valutazioni permettono l’allocazione di questi oggetti direttamente sullo stack piuttosto che sullo heap, e addirittura per piccoli oggetti la JVM può richiedere l’allocazione direttamente sui registri, aumentando ancor di più le prestazioni. Tutto questo lungo discorso fa intuire quanto l’ottimizzazione da parte della JVM conti e quanto può essere determinante in termini di prestazioni, ovviamente anche il fatto che Java non ha compilati ma byte-coded conta molto. La fonte di questo articolo è IBM se volete approfondire vi consiglio di seguire il link.

| | More

1 Comment

Other Links to this Post

RSS feed for comments on this post. TrackBack URI

Leave a comment

WordPress Themes