Измерение времени, проведенного на 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 с ]