Comment vérifier l'utilisation du processeur et de la mémoire en Java?

97

J'ai besoin de vérifier l'utilisation du processeur et de la mémoire pour le serveur en java, quelqu'un sait comment cela pourrait être fait?

Johnny Bou
la source

Réponses:

73

Si vous recherchez spécifiquement de la mémoire dans 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/>");

Cependant, ceux-ci ne doivent être considérés que comme une estimation ...

Jérémie
la source
Donc, si je suis runnin dans Eclipse, cela dépendra de mes paramètres Eclipse?
Café du
4
Notez que ce n'est pas la mémoire réellement utilisée - c'est la `` mémoire allouée '' qui signifie le tas que java a alloué, donc si vous avez -Xms90g et que votre application est très légère, vous obtiendrez toujours une mémoire allouée comme quelque chose de supérieur à 90g . Voir la réponse par "inconnu (yahoo)" supprimé ci-dessous (ce qui pourrait être différent à première vue)
0fnt
Juste curieux, pourquoi cela ne devrait-il être qu'une estimation?
ComputerScientist
@ComputerScientist Parce que gratuit est en fait ce qui est gratuit (après GC), il ne montre pas les objets en attente de GC. Pour obtenir BEAUCOUP plus précis, exécutez 2 garbage collection avant cette réponse. Si vous l'essayez avec et sans GC, vous trouverez les valeurs post-GC très cohérentes mais le preGC sera généralement au moins le double de celles-ci.
Bill K
@sbeliakov Vous pouvez utiliser JavaSysmon ( github.com/jezhumble/javasysmon ), bien que je vous recommande d'ouvrir une nouvelle question et je vais y répondre. La bibliothèque sur GitHub a un bogue et reconnaît 32 bits comme 64 bits, mais j'ai trouvé un moyen de mélanger différents jars [ github.com/goxr3plus/XR3Player/blob/master/resources/libs / ... ].
GOXR3PLUS
20
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();
    }
}
Dave
la source
ma compréhension que le sujet a commencé posait des questions sur la quantité de mémoire disponible dans le système d'exploitation. freeMemoryici renvoie la quantité de mémoire disponible dans JVM qui est très différente
Tagar
N'est-il pas étrange que votre classe SystemInfo ne commence pas par un Capital et que vos méthodes Info (), OSname (), MemInfo () le font?
Drswaki69
18

Si vous utilisez la JVM Sun et que vous êtes intéressé par l'utilisation de la mémoire interne de l'application (la quantité de mémoire allouée utilisée par votre application), je préfère activer la journalisation intégrée du garbage collection de la JVM. Vous ajoutez simplement -verbose: gc à la commande de démarrage.

À partir de la documentation Sun:

L'argument de ligne de commande -verbose: gc imprime des informations à chaque collection. Notez que le format de la sortie -verbose: gc est sujet à changement entre les versions de la plate-forme J2SE. Par exemple, voici la sortie d'une grande application serveur:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

Ici, nous voyons deux collections mineures et une majeure. Les chiffres avant et après la flèche

325407K->83000K (in the first line)

indiquent la taille combinée des objets vivants avant et après le garbage collection, respectivement. Après des collections mineures, le décompte comprend des objets qui ne sont pas nécessairement vivants mais qui ne peuvent pas être récupérés, soit parce qu'ils sont directement vivants, soit parce qu'ils sont dans ou référencés à partir de la génération titulaire. Le nombre entre parenthèses

(776768K) (in the first line)

est l'espace total disponible, sans compter l'espace dans la génération permanente, qui est le tas total moins l'un des espaces survivants. La collection mineure a pris environ un quart de seconde.

0.2300771 secs (in the first line)

Pour plus d'informations, voir: http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

Steve Blackwell
la source
17

D' ici

    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);
Danieln
la source
1
Et à propos de la mémoire?
Daniel De León
2
List <MemoryPoolMXBean> memoryPools = new ArrayList <MemoryPoolMXBean> (ManagementFactory.getMemoryPoolMXBeans ()); long usedHeapMemoryAfterLastGC = 0; for (MemoryPoolMXBean memoryPool: memoryPools) {if (memoryPool.getType (). equals (MemoryType.HEAP)) {MemoryUsage poolCollectionMemoryUsage = memoryPool.getCollectionUsage (); usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed (); }}
danieln
1
Merci pour la seule réponse montrant la récupération de l'utilisation du processeur.
Matthieu
1
Quelle est la différence entre faire ceci et simplement faire operatingSystemMXBean.getProcessCpuLoad();? Selon la documentation Oracle, cette méthode renvoie "Renvoie" l'utilisation récente du processeur "pour le processus de la machine virtuelle Java." Pourtant, je vois une différence de nombre relativement importante entre votre méthode et cette méthode.
Ishnark
1
@RobHall Il existe deux OperatingSystemMXBeanclasses. L'un est l'interface fournie dans java.lang. Mais il existe également une autre version, qui prolonge celle-ci com.sun.management. C'est la méthode dont je parlais à partir de làOperatingSystemMXBean
Ishnark
9

JMX, les MXBeans (ThreadMXBean, etc.) fournis vous donneront les utilisations de la mémoire et du processeur.

OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();
Javamann
la source
8

Pour l'utilisation de la mémoire, ce qui suit fonctionnera,

long total = Runtime.getRuntime().totalMemory();
long used  = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

Pour l'utilisation du processeur, vous devrez utiliser une application externe pour la mesurer.

Rich Adams
la source
5

Depuis Java 1.5, le JDK est livré avec un nouvel outil: JConsole qui peut vous montrer l'utilisation du processeur et de la mémoire de toute JVM 1.5 ou ultérieure. Il peut faire des graphiques de ces paramètres, exporter vers CSV, afficher le nombre de classes chargées, le nombre d'instances, les blocages, les threads etc ...

Telcontar
la source
4

Si vous utilisez la solution runtime / totalMemory qui a été publiée dans de nombreuses réponses ici (je l'ai beaucoup fait), assurez-vous de forcer d'abord deux garbage collection si vous voulez des résultats assez précis / cohérents.

Pour plus d'efficacité, Java permet généralement aux ordures de remplir toute la mémoire avant de forcer un GC, et même dans ce cas, ce n'est généralement pas un GC complet, donc vos résultats pour runtime.freeMemory () se situent toujours quelque part entre la quantité "réelle" de mémoire libre et 0 .

Le premier GC ne comprend pas tout, il en obtient l'essentiel.

L'avantage est que si vous faites simplement l'appel freeMemory (), vous obtiendrez un numéro qui est absolument inutile et qui varie considérablement, mais si vous faites d'abord 2 gc, c'est une jauge très fiable. Cela rend également la routine BEAUCOUP plus lente (en secondes, éventuellement).

Bill K
la source
3

L' objet Runtime de Java peut signaler l'utilisation de la mémoire de la JVM. Pour la consommation du processeur, vous devrez utiliser un utilitaire externe, comme le top Unix ou Windows Process Manager.

l'ombre de la lune
la source
2

Voici un code simple pour calculer l'utilisation actuelle de la mémoire en mégaoctets:

double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));
Phil
la source
2

J'ajouterais également la manière suivante pour suivre la charge du processeur:

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();
}

Vous pouvez en lire plus ici

sbeliakov
la source
1

JConsole est un moyen simple de surveiller une application Java en cours d'exécution ou vous pouvez utiliser un Profiler pour obtenir des informations plus détaillées sur votre application. J'aime utiliser le NetBeans Profiler pour cela.

blahspam
la source
1

Si vous utilisez Tomcat, consultez Psi Probe , qui vous permet de surveiller la consommation de mémoire interne et externe ainsi que de nombreux autres domaines.

Tim Howland
la source
0

Pour Eclipse, vous pouvez utiliser TPTP (Test and Performance Tools Platform) pour analyser l'utilisation de la mémoire et etc. plus d'informations

Fuang avec S.
la source