Как я могу контролировать использование процессора для каждого потока приложения Java в многопроцессорной среде Linux?

Я запускаю многопоточное Java-приложение в Linux RedHat 5.3 на машине с 8 ядрами (2 четырехъядерных процессора).

Я хочу отслеживать использование процессора каждым потоком, желательно относительно максимального процессора, который он может получить (один поток, работающий на 1 из ядер, должен достигать 100%, а не 12,5%).

Могу ли я сделать это с помощью jconsole/visualVM? Есть ли другой (надеюсь, бесплатный) инструмент?

Йоав


person Yoav Schwartz    schedule 05.11.2009    source источник


Ответы (3)


Если вы не хотите использовать специфические функции ОС, такие как обход каталога /proc, вы обычно можете получить нужные значения из интерфейса управления Java с помощью ThreadMXBean.getThreadCpuTime() и ThreadMXBean.getThreadUserTime().

person jarnbjo    schedule 05.11.2009

Как ответил jarnbjo, вы можете запросить JMX-бин управления потоками для процессора потока и времени пользователя:

import static org.junit.Assert.assertTrue;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import org.junit.Test;

public class ThreadStatsTest {

    @Test
    public void testThreadStats() throws Exception {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        assertTrue(threadMXBean.isThreadCpuTimeSupported());
        assertTrue(threadMXBean.isCurrentThreadCpuTimeSupported());

        threadMXBean.setThreadContentionMonitoringEnabled(true);
        threadMXBean.setThreadCpuTimeEnabled(true);
        assertTrue(threadMXBean.isThreadCpuTimeEnabled());

        ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds());
        for (ThreadInfo threadInfo2 : threadInfo) {
            long blockedTime = threadInfo2.getBlockedTime();
            long waitedTime = threadInfo2.getWaitedTime();
            long cpuTime = threadMXBean.getThreadCpuTime(threadInfo2.getThreadId());
            long userTime = threadMXBean.getThreadUserTime(threadInfo2.getThreadId());

            String msg = String.format(
                    "%s: %d ns cpu time, %d ns user time, blocked for %d ms, waited %d ms",
                    threadInfo2.getThreadName(), cpuTime, userTime, blockedTime, waitedTime);
            System.out.println(msg);
        }
    }
}
person mhaller    schedule 05.11.2009

Вы можете сделать вывод из файлов статистики в /proc/PID/ и /proc/PID/task/PID/. Проблема в том, что обычно создается много потоков (может быть, не с вашим приложением?), И эти файлы задач приходят и уходят. Однако родительский PID должен сообщать о времени пользователя/ядра в общем запланированном времени для всех процессов и, таким образом, сравнение с настенными часами должно дать вам хорошее начало.

person Jé Queue    schedule 05.11.2009