Профилирование потоков Java: определение потоков, ожидающих определенных блокировок и продолжительности каждого ожидания - PullRequest
2 голосов
/ 02 марта 2010

У меня есть приложение Java, использующее потоки, которое использует несколько экземпляров объекта Lock для синхронизации доступа к общим ресурсам.

Теперь, как часть измерения производительности, я хочу измерить время, затрачиваемое каждым потоком в каждой блокировке. Я уже пробовал профилировщик NetBeans.

Профилировщик Netbeans показывает мне общее время ожидания потока, но невозможно определить, сколько времени ожидала блокировка потока.

Какой инструмент вы порекомендуете для такого рода измерений?

Приветствия

1 Ответ

2 голосов
/ 02 марта 2010

В зависимости от того, какие именно данные вам нужны, вы можете просто получить эту информацию из вашей Java-программы.Например, что-то вроде этого будет производить выборку удерживаемых блокировок 20 раз в секунду в течение 100 секунд, эффективно создавая карту блокировок> приблизительное время блокировки (количество «тиков», в течение которых данная блокировка блокировалась):

private static void runProfile() {
    try {
        final int noSeconds = 100;
        final int sleepMillis = 50;
        final int noSamples = noSeconds * 1000 / sleepMillis;

        ThreadMXBean thb = ManagementFactory.getThreadMXBean();
        Map<String,Integer> blockCounts = new HashMap<String, Integer>(50);
        for (int i = 0; i < noSamples ; i++) {
            long[] ids = thb.getAllThreadIds();
            ThreadInfo[] infs = thb.getThreadInfo(ids, 0);
            for (ThreadInfo ti : infs) {
                LockInfo lockInf = ti.getLockInfo();
                if (lockInf != null) {
                    String key = lockInf.toString();
                    Integer cnt = blockCounts.get(key);
                    blockCounts.put(key, cnt == null ? 1 : cnt+1);
                }
            }

            Thread.sleep(sleepMillis);
        }

        System.out.println("Locks:");
        for (String lockName : blockCounts.keySet()) {
            System.out.println(lockName + " : " + blockCounts.get(lockName));
        }
    } catch (InterruptedException iex) {
        Thread.currentThread().interrupt();
    }
}

Адаптируйте для сбора данных по мере необходимости.

Затем вы можете начать это в фоновом потоке, например:

    Thread thr = new Thread() {
        public void run() {
            runProfile();
        }
    };
    thr.setPriority(Thread.MAX_PRIORITY-1);
    thr.start();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...