Как проверить использование ЦП и памяти в Java?

97

Мне нужно проверить использование процессора и памяти для сервера на java, кто-нибудь знает, как это можно сделать?

Джонни Боу
источник

Ответы:

73

Если вы ищете именно память в 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/>");

Однако это следует рассматривать только как приблизительную оценку ...

Джереми
источник
Итак, если я работаю в Eclipse, это будет зависеть от моих настроек Eclipse?
Кофе,
4
Обратите внимание, что это не фактическая используемая память - это `` выделенная память '', что означает кучу, которую выделила java, поэтому, если у вас есть -Xms90g и ваше приложение очень легкое, вы все равно получите allocatedMemory как что-то больше 90g . См. Ответ удаленного «unknown (yahoo)» ниже (который на первый взгляд может отличаться)
0fnt
Просто любопытно, почему это должна быть только оценка?
ComputerScientist
@ComputerScientist Поскольку бесплатно - это то, что на самом деле является бесплатным (после GC), оно не показывает объекты, ожидающие GC. Чтобы получить НАМНОГО точнее, запустите 2 сборки мусора перед этим ответом. Если вы попробуете его с GC и без него, вы обнаружите, что значения после GC очень согласованы, но preGC обычно будет как минимум вдвое больше.
Bill K
@sbeliakov Вы можете использовать JavaSysmon ( github.com/jezhumble/javasysmon ), хотя я рекомендую вам открыть новый вопрос, и я отвечу на него. Библиотека на GitHub имеет ошибку и распознает 32-разрядную версию как 64-разрядную, но я нашел работу по смешиванию разных jar- файлов [ 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();
    }
}
Дэйв
источник
Насколько я понимаю, тема началась с вопроса об объеме памяти, доступной в ОС. freeMemoryздесь возвращает объем доступной памяти в JVM , которая очень отличается
тагарскую
Разве не странно, что ваш класс SystemInfo не начинается с заглавной буквы, а ваши методы Info (), OSname (), MemInfo () делают?
Drswaki69
18

Если вы используете Sun JVM и вас интересует использование внутренней памяти приложением (сколько из выделенной памяти используется вашим приложением), я предпочитаю включить ведение журнала встроенной сборки мусора JVM. Вы просто добавляете -verbose: gc к команде запуска.

Из документации Sun:

Аргумент командной строки -verbose: gc печатает информацию для каждой коллекции. Обратите внимание, что формат вывода -verbose: gc может меняться между выпусками платформы J2SE. Например, вот вывод из большого серверного приложения:

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

Здесь мы видим две второстепенные коллекции и одну большую. Цифры до и после стрелки

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

указывают комбинированный размер живых объектов до и после сборки мусора соответственно. После второстепенных коллекций в счетчик включаются объекты, которые не обязательно живы, но не могут быть восстановлены либо потому, что они непосредственно живы, либо потому, что они находятся внутри или на которые ссылается временное поколение. Число в скобках

(776768K) (in the first line)

- это общее доступное пространство без учета пространства в постоянном поколении, которое представляет собой общую кучу за вычетом одного из оставшихся пространств. Незначительный сбор занял около четверти секунды.

0.2300771 secs (in the first line)

Для получения дополнительной информации см. Http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html.

Стив Блэквелл
источник
17

От сюда

    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);
Дэниел
источник
1
А по поводу памяти?
Даниэль Де Леон,
2
Список <MemoryPoolMXBean> memoryPools = new ArrayList <MemoryPoolMXBean> (ManagementFactory.getMemoryPoolMXBeans ()); long usedHeapMemoryAfterLastGC = 0; для (MemoryPoolMXBean memoryPool: memoryPools) {if (memoryPool.getType (). equals (MemoryType.HEAP)) {MemoryUsage poolCollectionMemoryUsage = memoryPool.getCollectionUsage (); usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed (); }}
danieln 01
1
Спасибо за единственный ответ, показывающий получение информации об использовании ЦП.
Матье
1
В чем разница между этим и простым действием operatingSystemMXBean.getProcessCpuLoad();? Согласно документации Oracle, этот метод возвращает «Возвращает« недавнее использование процессора »для процесса виртуальной машины Java». Тем не менее, я вижу относительно большую разницу между вашим методом и этим методом.
Ishnark
1
@RobHall Есть два OperatingSystemMXBeanкласса. Один из них - интерфейс, представленный в java.lang. Но есть и другая версия, расширяющая эту com.sun.management. Это метод, о котором я имел в виду, OperatingSystemMXBean
взято
9

JMX, MXBeans (ThreadMXBean и т. Д.) Предоставят вам информацию об использовании памяти и процессора.

OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();
Javamann
источник
8

Для использования памяти будет работать следующее:

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

Что касается использования ЦП, вам необходимо использовать внешнее приложение для его измерения.

Рич Адамс
источник
6

Начиная с Java 1.5 JDK поставляется с новым инструментом: JConsole, который может показать вам использование ЦП и памяти любой JVM версии 1.5 или новее. Он может создавать диаграммы этих параметров, экспортировать в CSV, показывать количество загруженных классов, количество экземпляров, взаимоблокировок, потоков и т. Д.

Telcontar
источник
4

Если вы используете решение runtime / totalMemory, которое было опубликовано во многих ответах здесь (я делал это много), обязательно сначала принудительно установите две сборки мусора, если вам нужны довольно точные / согласованные результаты.

Для повышения эффективности Java обычно позволяет мусору заполнить всю память перед принудительным сбором мусора, и даже тогда это обычно не полный сборщик мусора, поэтому ваши результаты для runtime.freeMemory () всегда находятся где-то между «реальным» объемом свободной памяти и 0 .

Первый сборщик мусора получает не все, а большую часть.

Подъем заключается в том, что если вы просто выполните вызов freeMemory (), вы получите число, которое абсолютно бесполезно и сильно варьируется, но если сначала выполнить 2 gc, это очень надежный измеритель. Это также делает процедуру НАМНОГО медленнее (возможно, секунды).

Билл К
источник
3

Объект Java Runtime может сообщать об использовании памяти JVM. Для использования ЦП вам придется использовать внешнюю утилиту, такую ​​как Unix's top или Windows Process Manager.

Лунная тень
источник
2

JConsole - это простой способ контролировать работающее приложение Java, или вы можете использовать Profiler, чтобы получить более подробную информацию о вашем приложении. Мне нравится использовать для этого NetBeans Profiler .

бласпам
источник
2

Вот простой код для расчета текущего использования памяти в мегабайтах:

double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));
Фил
источник
2

Я бы также добавил следующий способ отслеживания загрузки процессора:

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

Вы можете прочитать здесь

сбеляков
источник
1

Если вы используете Tomcat, обратите внимание на Psi Probe , который позволяет отслеживать потребление внутренней и внешней памяти, а также множество других областей.

Тим Хоуленд
источник
0

Для Eclipse вы можете использовать TPTP (Test and Performance Tools Platform) для анализа использования памяти и т. Д. Подробнее

Фуангвит С.
источник