Как я могу проверить использование процессора и памяти в Java?
Мне нужно проверить использование процессора и памяти для сервера в Java, кто-нибудь знает, как это можно сделать?
16 ответов
Если вы ищете специально в памяти 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/>");
Тем не менее, они должны быть приняты только в качестве оценки...
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();
}
}
Если вы используете 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
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);
JMX, предоставленные MXBean-компоненты (ThreadMXBean и т. Д.) Дадут вам использование памяти и ЦП.
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();
Для использования памяти будет работать следующее,
long total = Runtime.getRuntime().totalMemory();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
Для использования процессора вам понадобится внешнее приложение для его измерения.
Начиная с Java 1.5, JDK поставляется с новым инструментом: JConsole, который может показать вам использование процессора и памяти для любой 1.5 или более поздней JVM. Он может делать диаграммы этих параметров, экспортировать в CSV, показывать количество загруженных классов, количество экземпляров, взаимоблокировок, потоков и т. Д.
Java Runtime объект может сообщить об использовании памяти JVM. Для использования процессора вам нужно будет использовать внешнюю утилиту, например, Unix top или Windows Process Manager.
Если вы используете решение runtime/totalMemory, которое было опубликовано во многих ответах здесь (я много делал), сначала обязательно запустите две сборки мусора, если вы хотите достаточно точные / согласованные результаты.
Для эффективности Java обычно позволяет мусору заполнить всю память перед форсированием GC, и даже тогда это обычно не полный GC, поэтому ваши результаты для runtime.freeMemory() всегда будут где-то между "реальным" объемом свободной памяти и 0,
Первый GC не получает всего, он получает большую часть этого.
Подъем заключается в том, что если вы просто сделаете вызов freeMemory (), вы получите абсолютно бесполезный номер, который варьируется в широких пределах, но если сделать сначала 2 gc, это очень надежный датчик. Это также делает процедуру намного медленнее (возможно, секунд).
Вот простой код для расчета текущего использования памяти в мегабайтах:
double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));
JConsole - это простой способ отслеживать работающее Java-приложение, или вы можете использовать Profiler для получения более подробной информации о вашем приложении. Мне нравится использовать для этого Профилировщик NetBeans.
Я бы также добавил следующий способ отслеживания загрузки процессора:
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();
}
Вы можете прочитать больше здесь
Java-профилировщик YourKit является отличным коммерческим решением. Вы можете найти дополнительную информацию в документации по профилированию процессора и памяти.
Если вы используете Tomcat, проверьте Psi Probe, который позволяет отслеживать потребление внутренней и внешней памяти, а также множество других областей.
Я хочу добавить примечание к существующим ответам:
Эти методы отслеживают только память JVM. Фактический процесс может потреблять больше памяти.
java.nio.ByteBuffer.allocateDirect() — это функция/библиотека, которую легко пропустить, и действительно выделенная собственная память, которая не является частью управления памятью Java.
В Linux вы можете использовать что-то вроде этого, чтобы получить фактически потребляемую память: https://linuxhint.com/check_memory_usage_process_linux/
Для Eclipse вы можете использовать TPTP (Test and Performance Tools Platform) для анализа использования памяти и т. Д. Дополнительная информация