Измерение времени, проведенного на GC в JVM

Предположим, я тестирую приложение на сервере Java. Я знаю, сколько времени нужно, чтобы закончить тест. Теперь я хотел бы знать, сколько было потрачено на GC во время этого теста. Как мне это сделать?

7 ответов

Решение

Самый простой способ - это использовать -Xloggc а также -XX:-PrintGCTimeStamps варианты при запуске вашей JVM. Я думаю, что это печатает, сколько времени занимает сборка мусора.

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

Я предполагаю, что когда GC (Garbage Collector) работает, приложение останавливается и возобновляет работу после завершения GC.

Я не думаю, что это безопасное предположение. Вы уверены, что сборщик мусора не работает параллельно с кодом вашего приложения?

Чтобы измерить время, затрачиваемое на сбор мусора, вы можете запросить сборщик мусора MXBean.

Попробуй это:

public static void main(String[] args)  {
    System.out.println("collectionTime = " + getGarbageCollectionTime());
}

private static long getGarbageCollectionTime() {
    long collectionTime = 0;
    for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
        collectionTime += garbageCollectorMXBean.getCollectionTime();
    }
    return collectionTime;
}

Этот показатель производительности записывается JVM и становится доступным через JMX. Для интерактивного мониторинга подключитесь к работающей JVM с помощью JConsole, и на вкладке "Сводная информация о виртуальной машине" отобразится что-то вроде:

Сборщик мусора: Имя = 'Копировать', Коллекции = 26, Общее время, потраченное = 0,183 секунды Сборщик мусора: Имя = 'MarkSweepCompact', Коллекции = 2, Общее время, потраченное = 0,168 секунды

Вы также можете запросить JMX программно.

Еще одно удобное решение - запустить jstat -gc ( документация) против вашего процесса, когда ваши тесты сделаны. Это даст вам хороший агрегированный вывод о том, сколько именно времени было потрачено в GC за время существования вашей JVM.

Включить журналы сбора мусора. Как задокументировано, вы можете использовать -verbose:gc, -XX:+PrintGCDetails а также -XX:+PrintGCTimeStamps флаги. -Xloggc Флаг может быть использован, чтобы направить их в файл.

Полученные журналы удобочитаемы, но для большей пользы вы, вероятно, захотите, чтобы они запускались через анализатор. Такие инструменты перечислены в этой теме.

Подобно ответу @Steve McLeod, в котором используется ManagementFactory, начиная с Java 8, его также можно записать в одну строку с использованием потоков Java:

long collectionTime = ManagementFactory.getGarbageCollectorMXBeans().stream().mapToLong(mxBean -> mxBean.getCollectionTime()).sum();

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

Вы можете запустить свое приложение с помощью следующих параметров командной строки -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails и получить информацию о GC.

Вот пример сообщения журнала:

2012-12-17T03: 02: 15.590-0500: [GC [PSYoungGen: 40934K-> 2670K (29440K)] 48211K-> 14511K (73152K), 0,5745260 с] [Times: user=0,08 sys = 0,01, real = 0,58 с ]

Другие вопросы по тегам