Як перевірити використання процесора та пам'яті в Java?


97

Мені потрібно перевірити використання процесора та пам'яті для сервера в Java, хтось знає, як це можна зробити?


Можливо, ці посилання будуть корисними: javaworld.com/javaworld/javaqa/2002-11/01-qa-1108-cpu.html roseindia.net/javatutorials/…
chessguy

Відповіді:


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 і ваш додаток дуже легкий, ви все одно отримаєте alloMemory як щось більше, ніж 90g . Дивіться відповідь на видалене "невідомо (yahoo)" нижче (яке може відрізнятися на перший погляд)
0fnt

Просто цікаво, чому це має бути лише оцінка?
ComputerScientist

@ComputerScientist Оскільки безкоштовне - це насправді те, що є безкоштовним (після GC), воно не відображає об'єкти, які чекають GC. Щоб набагато точніше запустити 2 збірки сміття перед цією відповіддю. Якщо ви спробуєте це з GC та без нього, ви знайдете значення після GC дуже послідовними, але preGC, як правило, буде принаймні вдвічі більшим.
Білл К

@sbeliakov Ви можете використовувати JavaSysmon ( github.com/jezhumble/javasysmon ), хоча я рекомендую вам відкрити нове питання, і я відповім на нього. Бібліотека на GitHub має помилку і розпізнає 32-біт як 64-біт, але я знайшов роботу навколо змішування різних банок [ 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
List <MemoryPoolMXBean> memoryPools = new ArrayList <MemoryPoolMXBean> (ManagementFactory.getMemoryPoolMXBeans ()); long usedHeapMemoryAfterLastGC = 0; для (MemoryPoolMXBean memoryPool: memoryPools) {if (memoryPool.getType (). дорівнює (MemoryType.HEAP)) {MemoryUsage poolCollectionMemoryUsage = memoryPool.getCollectionUsage (); usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed (); }}
danieln

1
Дякуємо за єдину відповідь, що показує пошук використання процесора.
Матьє

1
Яка різниця між цим і простим operatingSystemMXBean.getProcessCpuLoad();? Згідно з документацією Oracle, цей метод повертає "Повертає" нещодавнє використання процесора "для процесу віртуальної машини Java." Проте я бачу порівняно велику різницю між вашим методом та цим методом.
Ішнарк

1
@RobHall Є два OperatingSystemMXBeanкласи. Одним з них є інтерфейс, наданий в java.lang. Але є також інша версія, яка поширює цю на com.sun.management. Це метод, про який я мав на увазі, - з цьогоOperatingSystemMXBean
Ішнарк

9

Надані JMX, MXBeans (ThreadMXBean та ін.) Забезпечать вам використання пам’яті та процесора.

OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();

8

Для використання пам'яті буде працювати наступне:

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

Для використання процесора вам потрібно буде використовувати зовнішню програму для його вимірювання.


5

Оскільки Java 1.5 JDK постачається з новим інструментом: JConsole, який може показати вам використання центрального процесора та пам'яті будь-якої версії JVM 1.5 або пізнішої версії. Він може робити діаграми цих параметрів, експортувати в CSV, показувати кількість завантажених класів, кількість екземплярів, тупикових ситуацій, потоків тощо ...


4

Якщо ви використовуєте рішення runtime / totalMemory, яке було опубліковано у багатьох відповідях тут (я це вже багато робив), переконайтеся, що спочатку вимушено збираєте два сміття, якщо хочете отримати досить точні / послідовні результати.

Для ефективності Java зазвичай дозволяє сміттю заповнювати всю пам'ять перед форсуванням GC, і навіть тоді це, як правило, не є повноцінним GC, тому ваші результати для runtime.freeMemory () завжди знаходяться десь між "реальним" обсягом вільної пам'яті і 0 .

Перший GC отримує не все, він отримує більшу частину.

Підйом полягає в тому, що якщо ви просто зробите виклик freeMemory (), ви отримаєте абсолютно марний номер, який коливається в широких межах, але якщо зробити перший об'єм 2 гк, це дуже надійний показник. Це також робить рутину НАБАГАТО повільнішою (можливо, секунди).


3

Об'єкт середовища виконання Java може повідомляти про використання пам'яті JVM. Для споживання процесора вам доведеться використовувати зовнішню утиліту, наприклад, вершину Unix або диспетчер процесів Windows.


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

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



1

Якщо ви використовуєте Tomcat, перевірте Psi Probe , який дозволяє контролювати споживання внутрішньої та зовнішньої пам'яті, а також безліч інших областей.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.