Feb 5

Oggi ho voluto fare un test di performance molto semplice con java per cercare di migliore al massimo le performance nella esecuzione di contenuti dinamici di un sito web, senza tralasciare il discorso garbage collector. Per fare ciò ho realizzato una semplicissima classe che “spreca” un po’ di tempo nel fare operazioni inutili e l’ho fatta girare con vari settaggi. Riporto il codice sorgente della pagina di seguito è una classe semplicissima.

/*
* Testperformace.java
*
* @author l.ciocci
* Created on 5 febbraio 2010, 10.09
*
* Questa è una classe di esempio per verificare le performance della JVM.
* L'idea è quella di verificare le differenze tra la jvm in configurazione
* server e quella in versione standar
*
* Provare ad eseguire con
* java -server Testperformace
*
* oppure
*
* java -client Testperformance
*/

import java.util.LinkedList;
import java.lang.StringBuffer;

public class Testperformace {

public static void main(String[] args) {
long start=System.currentTimeMillis();
LinkedList list=new LinkedList();
StringBuffer sb=new StringBuffer();
System.out.println("Inizio l'esecuzione di Testperformance\n");

//Perdo un po' di tempo
for (int i=0;i<10000;i++) {
//Genero un numero casuale e lo memorizzo nella linked list
String str=new String();
sb.append(i);
str=sb.toString();
list.add(str);
//if (i%1000==0) System.out.print(".." + i);
}

long stop=System.currentTimeMillis();
long time=stop-start;
System.out.println("\nL'esecuzione ha impiegato: " + time + " millisecondi");
}

}

La classe usa un banale conteggio dei millisecondi passati dall’inizializzazione fino al termine dell’esecuzione.
La versione di java che utilizzo è la OpenJDK Runtime Environment (build 1.6.0_0-b11).

Ho fatto varie prove di esecuzione lanciando la classe con il comando:
java -server Testperformace

L’esecuzione ha impiegato: 895 millisecondi (Ovviamente le performance dipendono dalla configurazione hardware e software della vostra Workstation). Le successive esecuzioni hanno dato tempi comparabili.
Utilizzado lo switch:

java -client Testperformace

L’esecuzione ha impiegato: 760 millisecondi. E gli altri test hanno dato tempi comparabili.

Ma la cosa che mi ha sorpreso più di tutte è questo swith passato alla JVM, un po’ “segreto”:

java -XX:+AggressiveHeap Testperformace

In questo caso il tempo medio per eseguire l’applicazione è stato di soli: 391 millisecondi!!!

Ho poi fatto qualche altro test su pagine JSP ottendo ottimi benefici in termini di velocità. Lo switch in questione però impedisce di fare un corretto profiling della memoria con Netbeans (almeno nella mia Linux Box) e di non sembra funzionare bene in debug. Lo switch -XX:+AggressiveHeap sembra destinato all’uso di applicazioni che devono girare per lunghi periodi senza dovere essere riavviate. Molto Interessante!!!


Jan 20

Ecco una cosa di cui si parla molto, ma di cui si sa “relativamente” poco. I linguaggi object oriented ci hanno abituato molto bene, ci consentono di creare e distruggere oggetti in modo molto semplice senza doverci occupare della gestione della memoria: chi ha utilizzato il C si ricorderà della funzione malloc per allocare la giusta quantità di memoria ad esempio per un’array, chi utilizza solamente Java penserà che cosa inutile basta dichiarare:

ArrayList array=new ArrayList();

senza occuparmi di quanta memoria utilizza l’array!

In una applicazione web (o desktop) dichiariamo gli oggetti che ci servono li usiamo e alla fine ce ne dimentichiamo, tanto implicitamente è naturale pensare “ci pensa il garbage collector”. Ma è sempre vero? La risposta è semplicemente “No”. Il garbage collector funziona bene, ma non è perfetto e può essere aiutato da qualche semplice accorgimento.

Questo è poi particolarmente vero per le applicazioni web che magari devono funzionare per diversi giorni (o mesi) senza essere mai riavviate. Nelle applicazioni desktop infatti nella peggiore delle ipotesi si “blocca” la singola applicazione. Chiudendo il programma o facendolo ripartire in linea teorica torna tutto come prima.
Nel caso di un sito web dinamico o di una applicazione web invece si blocca l’intero sito precludendo di fatto l’utilizzo dei servizi o la consultazione da parte degli utenti collegati. In questa serie di articoli farò riferimento alle applicazioni web in particolare modo ed al loro sviluppo con Java.

In primo luogo un buon design del codice permette di evitare sprechi inutili di memoria. In secondo luogo non dobbiamo mai dimenticare che una pagina web può essere visitata da più di un utente contemporaneamente, e quindi sicuramente spreca molte risolte, anche in questo caso un design pulito aiuta a risparmiare memoria ed incrementare prestazioni.

In ogni caso anche un sito web concepito in modo assolutamente perfetto necessita di una determinata quantità di memoria per funzionare. E java permette di specificare quanta memoria assegnare alla Java Virtual Machine (JVM) tramite l’utilizzo della variabile JAVA_OPTS.


JAVA_OPTS=" -Xmx764m -Xms256m -server"

In questa riga ci sono 4 parametri interessanti che saranno passati alla JVM
-Xmx764m indica di utilizzare fino a 764 megabyte di memoria per l’heap
-Xms256m indica di utilizzare un minimo di 256 megabyte di memoria per l’heap
-server indica alla JVM di funzionare in modalità server, in questa modalità la JVM ha una migliore gestione del garbage collector (inoltre c’è chi dice che ha performance superiori, ma non ho ancora verificato).

…continua a presto!!!