Newsgroup: it.comp.java
Titolo: JMX e dati sfalsati

Stò cercando di valutare le prestazioni di un mio software, in particolare  
tempi d'esecuzione e memoria richiesta.
Per far questo, mi è parso di capire si faccia così, ho creato un main,  
utilizzato la tecnologia JMX, con cui chiamo la mia applicazione e scrivo  
su file le prestazione ricavate.
Solo che facendo così nella memoria usata viene conteggiata anche quella  
necessaria all'esecuzione del main, e considerando che per fare il suo  
mestiere ha due cicli annidati e la generazione dei parametri per  
l'applicazione la differenza non è poca.
Avevo pensato di prendere la memoria utilizzata prima dell'esecuzione  
dell'applicazione ed sottrarre questo valore dai risultati ottenuti, ma  
così facendo se a metà dell'esecuzione mi parte il gc i dati perdono di  
significato.
Qualche suggerimento?
Il codice per ora è il seguente:
public class Main implements javax.management.NotificationListener {
     public static void main(String argv[]) {
         if(argv.length==1) {
             PrintWriter pw = null;
             try {
                 pw = new PrintWriter(new FileWriter(argv[0]));
                 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
                 NotificationEmitter emitter = (NotificationEmitter) mbean;
                 Main listener = new Main(mbean,pw);
                 List<MemoryPoolMXBean> pools =  
ManagementFactory.getMemoryPoolMXBeans();
                 for (int i = 0; i < pools.size(); i++) {
                     MemoryPoolMXBean pool = pools.get(i);
                     if (pool.isCollectionUsageThresholdSupported()) {
                         pool.setCollectionUsageThreshold(5120l);
                     }
                     if (pool.isUsageThresholdSupported()) {
                         pool.setUsageThreshold(1024l);
                     }
                 }
                 emitter.addNotificationListener(listener, null, null);
                 MBeanServer server =  
ManagementFactory.getPlatformMBeanServer();
                 ObjectName[] name = {new ObjectName("test:name=uno"), new  
ObjectName("test:name=due"), new ObjectName("test:name=tre")};
                 server.registerMBean(new Classe1Test(), name[0]);
                 server.registerMBean(new Classe2Test(), name[1]);
                 server.registerMBean(new Classe3Test(), name[2]);
                 for (int i = 1; i < 21; i++) {
                     String file = Classe4.myPath + "Es" + i;
                     pw.println("%%%%%%%%%%%%%%%%%%\n"+file);
                     for (int j = 0; j < name.length; j++) {
                         pw.println("------------------\n"+name[j]);
                         pw.println(server.invoke(name[j], "run", new  
String[]{file}, new String[]{"java.lang.String"})+"------------------\n");
                     }
                     pw.println("%%%%%%%%%%%%%%%%%%\n");
                 }
                 pw.flush();
             } catch (IOException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (InstanceNotFoundException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (ReflectionException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (MBeanException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (InstanceAlreadyExistsException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (NotCompliantMBeanException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (MalformedObjectNameException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } catch (NullPointerException ex) {
                 Logger.getLogger(Main.class.getName()).log(Level.SEVERE,  
null, ex);
             } finally {
                 pw.close();
             }
         }
     }
     private MemoryMXBean bean;
     private PrintWriter pw;
     private Main(MemoryMXBean mbean,PrintWriter pw) {
         bean=mbean;
 
this.pw
=pw;
     }
     @Override
     public void handleNotification(Notification notification, Object  
handback) {
         MemoryUsage mu=bean.getHeapMemoryUsage();
         pw.println("Heap usage: "+mu.getUsed()+"/"+mu.getCommitted());
         mu=bean.getNonHeapMemoryUsage();
         pw.println("Non Heap usage: "+mu.getUsed()+"/"+mu.getCommitted());
     }
}
Grazie per l'attenzione
-- 
Mail to: anforagimailpuntocom²
http://www.hostingjava.it/-SaThot/mail/me

Ciao, io di solito faccio così, ma non ho mai potuto appurare la
correttezza di questi risultati
/**
 * Created by IntelliJ IDEA.
 * User: Giordano "Mejoro" Fidilio
 * Date: 23-ott-2008
 * Time: 22.53.35
 * .... To change this template use File | Settings | File Templates.
 */
public class Main {
    public static void main (String[] args)
    {
        SystemData.initTime(); // inizio a contare le risorse di tempo
& memoria …
        ////////////////////////
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
        {
        System.out.println("Faccio Qualcosa");
        int unaVariabile = 5;
        }
        out("\r\n\t -> " + SystemData.infoStr());  // oppure  String
str = <NOME_PACKAGE>.SystemData.infoPrompt();
    }
    // METODI
    private static void nl() { System.out.println(); }
    private static void out (Object o) { System.out.println(o.toString
()); }
}
//\\//\\//\\//\\//\\//\\
/*public*/ class SystemData {
    // CAMPI
    private static Runtime R = Runtime.getRuntime();
    private static double time0;
    // NESSUN COSTRUTTORE PER QUESTA CLASSE.
    // METODI
    public static void initTime() {		// QUESTA FUNZ. VIENE INVOCATA
ALL'INIZIO DEL Main: avvia la conta delle
	time0 = System.currentTimeMillis();	// risorse di tempo e memoria che
verranno impiegate nell'esecuzione di
    }                                   // tutto il programma
    public static double askTime() {
	return (System.currentTimeMillis() - time0) / 1000.;
    }
    public static double askMemory() {
	R.gc();
	return (R.totalMemory() - R.freeMemory()) / 1024. / 1024.;
    }
    public static String memoryUsage() {
	java.text.NumberFormat nf = new java.text.DecimalFormat("0.###");
	R.gc();
	return nf.format ( askMemory() );
    }
    public static void infoPrompt() {
	String margineSX = "\r\n\t\t", spazio_centrale = "\t\t";
	System.out.print ("\r\n" + margineSX);
	    String strTime = "Tempo = " + askTime() + " secondi";
	    String strMemo = "Memoria = " + memoryUsage() + " MegaByte";
	int lunT = strTime.length();
	int lunM = strMemo.length();
	System.out.print (strTime);
	System.out.print (spazio_centrale);
	System.out.print (strMemo);
	System.out.print (margineSX);
	for (int i = 0; i < lunT; i++) System.out.print ('\257'); // DOPPIE
FRECCINE VERSO SX
	System.out.print (spazio_centrale);
	for (int i = 0; i < lunM; i++) System.out.print ('\256'); // DOPPIE
FRECCINE VERSO DX
	System.out.println("\r\n");
    }
    public static String infoStr() {
        return new StringBuilder()
                .append("Tempo = ").append(askTime()).append("
secondi")
                .append("\t")
                .append("Memoria = ").append(memoryUsage()).append("
MegaByte")
                .toString();
    }
}