Devo controllare l'utilizzo della CPU e della memoria per il server in Java, qualcuno sa come potrebbe essere fatto?
Devo controllare l'utilizzo della CPU e della memoria per il server in Java, qualcuno sa come potrebbe essere fatto?
Risposte:
Se stai cercando specificamente la memoria in JVM:
Runtime runtime = Runtime.getRuntime();
NumberFormat format = NumberFormat.getInstance();
StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
sb.append("free memory: " + format.format(freeMemory / 1024) + "<br/>");
sb.append("allocated memory: " + format.format(allocatedMemory / 1024) + "<br/>");
sb.append("max memory: " + format.format(maxMemory / 1024) + "<br/>");
sb.append("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) + "<br/>");
Tuttavia, questi dovrebbero essere presi solo come una stima ...
package mkd.Utils;
import java.io.File;
import java.text.NumberFormat;
public class systemInfo {
private Runtime runtime = Runtime.getRuntime();
public String Info() {
StringBuilder sb = new StringBuilder();
sb.append(this.OsInfo());
sb.append(this.MemInfo());
sb.append(this.DiskInfo());
return sb.toString();
}
public String OSname() {
return System.getProperty("os.name");
}
public String OSversion() {
return System.getProperty("os.version");
}
public String OsArch() {
return System.getProperty("os.arch");
}
public long totalMem() {
return Runtime.getRuntime().totalMemory();
}
public long usedMem() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
public String MemInfo() {
NumberFormat format = NumberFormat.getInstance();
StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
sb.append("Free memory: ");
sb.append(format.format(freeMemory / 1024));
sb.append("<br/>");
sb.append("Allocated memory: ");
sb.append(format.format(allocatedMemory / 1024));
sb.append("<br/>");
sb.append("Max memory: ");
sb.append(format.format(maxMemory / 1024));
sb.append("<br/>");
sb.append("Total free memory: ");
sb.append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
sb.append("<br/>");
return sb.toString();
}
public String OsInfo() {
StringBuilder sb = new StringBuilder();
sb.append("OS: ");
sb.append(this.OSname());
sb.append("<br/>");
sb.append("Version: ");
sb.append(this.OSversion());
sb.append("<br/>");
sb.append(": ");
sb.append(this.OsArch());
sb.append("<br/>");
sb.append("Available processors (cores): ");
sb.append(runtime.availableProcessors());
sb.append("<br/>");
return sb.toString();
}
public String DiskInfo() {
/* Get a list of all filesystem roots on this system */
File[] roots = File.listRoots();
StringBuilder sb = new StringBuilder();
/* For each filesystem root, print some info */
for (File root : roots) {
sb.append("File system root: ");
sb.append(root.getAbsolutePath());
sb.append("<br/>");
sb.append("Total space (bytes): ");
sb.append(root.getTotalSpace());
sb.append("<br/>");
sb.append("Free space (bytes): ");
sb.append(root.getFreeSpace());
sb.append("<br/>");
sb.append("Usable space (bytes): ");
sb.append(root.getUsableSpace());
sb.append("<br/>");
}
return sb.toString();
}
}
freeMemory
qui restituisce la quantità di memoria disponibile in JVM che è molto diversa
Se stai utilizzando Sun JVM e sei interessato all'utilizzo della memoria interna dell'applicazione (quanta memoria allocata sta utilizzando la tua app), preferisco attivare la registrazione della garbage collection incorporata nella JVM. Devi semplicemente aggiungere -verbose: gc al comando di avvio.
Dalla documentazione Sun:
L'argomento della riga di comando -verbose: gc stampa le informazioni in ogni raccolta. Notare che il formato dell'output -verbose: gc è soggetto a modifiche tra i rilasci della piattaforma J2SE. Ad esempio, ecco l'output di un'applicazione server di grandi dimensioni:
[GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs]
Qui vediamo due raccolte minori e una maggiore. I numeri prima e dopo la freccia
325407K->83000K (in the first line)
indicare la dimensione combinata degli oggetti attivi prima e dopo la raccolta dei rifiuti, rispettivamente. Dopo raccolte minori, il conteggio include oggetti che non sono necessariamente vivi ma che non possono essere recuperati, perché sono direttamente vivi o perché appartengono o fanno riferimento alla generazione di ruolo. Il numero tra parentesi
(776768K) (in the first line)
è lo spazio disponibile totale, senza contare lo spazio nella generazione permanente, che è l'heap totale meno uno degli spazi superstiti. La raccolta minore ha richiesto circa un quarto di secondo.
0.2300771 secs (in the first line)
Per maggiori informazioni, vedere: http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
Da qui
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
long prevUpTime = runtimeMXBean.getUptime();
long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
double cpuUsage;
try
{
Thread.sleep(500);
}
catch (Exception ignored) { }
operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long upTime = runtimeMXBean.getUptime();
long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
long elapsedCpu = processCpuTime - prevProcessCpuTime;
long elapsedTime = upTime - prevUpTime;
cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
System.out.println("Java CPU: " + cpuUsage);
operatingSystemMXBean.getProcessCpuLoad();
? Secondo la documentazione Oracle, questo metodo restituisce "Restituisce l '" utilizzo recente della CPU "per il processo Java Virtual Machine." Tuttavia vedo una differenza numerica relativamente grande tra il tuo metodo e questo metodo.
OperatingSystemMXBean
classi. Uno è l'interfaccia fornita in java.lang
. Ma c'è anche un'altra versione, che estende questa in com.sun.management
. Questo è il metodo a cui mi riferivo è da quelloOperatingSystemMXBean
Per l'utilizzo della memoria, funzionerà quanto segue,
long total = Runtime.getRuntime().totalMemory();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
Per l'utilizzo della CPU, è necessario utilizzare un'applicazione esterna per misurarlo.
A partire da Java 1.5, JDK viene fornito con un nuovo strumento: JConsole che può mostrare l'utilizzo della CPU e della memoria di qualsiasi JVM 1.5 o successiva. Può creare grafici di questi parametri, esportare in CSV, mostrare il numero di classi caricate, il numero di istanze, deadlock, thread ecc ...
Se utilizzi la soluzione runtime / totalMemory che è stata pubblicata in molte risposte qui (l'ho fatto molte volte), assicurati di forzare prima due raccolte di rifiuti se desideri risultati abbastanza accurati / coerenti.
Per l'efficienza Java di solito consente a spazzatura di riempire tutta la memoria prima di forzare un GC, e anche in questo caso di solito non è un GC completo, quindi i risultati per runtime.freeMemory () sono sempre da qualche parte tra la quantità "reale" di memoria libera e 0 .
Il primo GC non ottiene tutto, ne ottiene la maggior parte.
La ripresa è che se fai solo la chiamata freeMemory () otterrai un numero che è assolutamente inutile e varia ampiamente, ma se fai prima 2 gc è un indicatore molto affidabile. Rende anche la routine MOLTO più lenta (forse secondi).
L' oggetto Runtime di Java può segnalare l'utilizzo della memoria della JVM. Per il consumo della CPU dovrai usare un'utilità esterna, come il top di Unix o Windows Process Manager.
JConsole è un modo semplice per monitorare un'applicazione Java in esecuzione oppure puoi utilizzare un Profiler per ottenere informazioni più dettagliate sulla tua applicazione. Mi piace usare NetBeans Profiler per questo.
Aggiungerei anche il seguente modo per tenere traccia del carico della CPU:
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
double getCpuLoad() {
OperatingSystemMXBean osBean =
(com.sun.management.OperatingSystemMXBean) ManagementFactory.
getPlatformMXBeans(OperatingSystemMXBean.class);
return osBean.getProcessCpuLoad();
}
Puoi leggere di più qui
Il profiler Java YourKit è un'ottima soluzione commerciale. Ulteriori informazioni sono disponibili nei documenti sulla profilazione della CPU e la profilazione della memoria .
Se stai usando Tomcat, controlla Psi Probe , che ti consente di monitorare il consumo di memoria interna ed esterna, nonché una miriade di altre aree.
Per Eclipse, è possibile utilizzare TPTP (Test and Performance Tools Platform) per analizzare l'utilizzo della memoria e altre informazioni