Сообщения журнала сборки мусора Java

96

Я настроил Java для сброса информации о сборке мусора в журналы ( подробный сборщик мусора ). Я не уверен, что означают записи о сборке мусора в журналах. Образец этих записей размещен ниже. Я искал в Google и не нашел убедительных объяснений.

У меня есть несколько разумных предположений, но я ищу ответы, которые содержат строгие определения того, что означают числа в записях, и подкреплены надежными источниками. Автоматический +1 ко всем ответам, цитирующим документацию Sun. Мои вопросы:

  1. Что означает PSYoungGen? Я предполагаю, что это как-то связано с предыдущим (младшим?) Поколением, но что именно?
  2. В чем разница между второй тройкой чисел и первой?
  3. Почему имя (PSYoungGen) указано для первой тройки чисел, а не для второй?
  4. Что означает каждое число (размер памяти) в тройке. Например, в 109884K-> 14201K (139904K) это память перед GC 109884k, а затем она уменьшается до 14201K. Насколько актуален третий номер? Зачем нам нужен второй набор чисел?

8109.128: [GC [PSYoungGen: 109884K-> 14201K (139904K)] 691015K-> 595332K (1119040K), 0,0454530 сек]

8112.111: [GC [PSYoungGen: 126649K-> 15528K (142336K)] 707780K-> 605892K (1121472K), 0,0934560 с]

8112.802: [GC [PSYoungGen: 130344K-> 3732K (118592K)] 720708K-> 607895K (1097728K), 0,0682690 сек]

Итан Хейлман
источник
вся куча, молодое поколение, часть кучи, второстепенный gc, чтобы узнать, как работает gc, проверьте, например, cubrid.org/blog/dev-platform/…
MarianP

Ответы:

90

Большая часть этого объяснена в Руководстве по настройке сборщика мусора (которое вам все равно стоит прочитать).

Параметр командной строки -verbose:gcпозволяет выводить информацию о куче и сборке мусора при каждой сборке. Например, вот вывод из большого серверного приложения:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

Здесь мы видим две второстепенные коллекции, за которыми следует одна большая коллекция. Цифры до и после стрелки (например, 325407K->83000Kв первой строке) указывают комбинированный размер живых объектов до и после сборки мусора соответственно. После небольших коллекций размер включает в себя некоторые объекты, которые являются мусором (больше не живы), но не могут быть восстановлены. Эти объекты либо содержатся в существующем поколении, либо ссылаются на временное или постоянное поколение.

Следующее число в скобках (например, (776768K)снова из первой строки) - это зафиксированный размер кучи: объем пространства, используемого для объектов Java без запроса дополнительной памяти от операционной системы. Обратите внимание, что это число не включает одно из оставшихся пространств, так как только одно может использоваться в любой момент времени, а также не включает постоянное поколение, которое содержит метаданные, используемые виртуальной машиной.

Последний элемент в строке (например, 0.2300771 secs) указывает время, необходимое для выполнения сбора; в этом случае примерно четверть секунды.

Формат основной коллекции в третьей строке аналогичен.

Формат вывода, производимого -verbose:gcв будущих версиях, может быть изменен.

Я не уверен, почему в вашем PSYoungGen; вы меняли сборщик мусора?

Майкл Майерс
источник
Где найти файлы журнала gc?
Mr Lou
7
Этот ответ на самом деле не отвечает на исходные вопросы. Я считаю, что ответ Михаэля Джозефа лучше. Он отвечает на вопросы, заданные Итаном, и лучше разбирается в исходном примере. Хотя в его ответе есть две проблемы (его ссылка теперь мертва, а rafa.ferreria указал на другую), он не просто извергает документ Oracle.
Дирк
127
  1. PSYoungGen относится к сборщику мусора, используемому для второстепенной сборки. PS расшифровывается как Parallel Scavenge.
  2. Первый набор чисел - это размеры до / после молодого поколения, а второй набор - для всей кучи. ( Диагностика проблемы со сборкой мусора подробно описывает формат)
  3. Имя указывает на генерацию и рассматриваемый сборщик, второй набор - для всей кучи.

Пример ассоциированного полного GC также показывает коллекторы, используемые для старого и постоянного поколений:

3.757: [Full GC [PSYoungGen: 2672K->0K(35584K)] 
            [ParOldGen: 3225K->5735K(43712K)] 5898K->5735K(79296K) 
            [PSPermGen: 13533K->13516K(27584K)], 0.0860402 secs]

Наконец, разбив одну строку вашего примера вывода журнала:

8109.128: [GC [PSYoungGen: 109884K->14201K(139904K)] 691015K->595332K(1119040K), 0.0454530 secs]
  • 107 МБ используется до GC, 14 МБ используется после GC, максимальный размер молодого поколения 137 МБ
  • 675 МБ кучи перед сборкой мусора , 581 МБ кучи после сборки мусора, максимальный размер кучи 1 ГБ
  • второстепенный сборщик мусора произошел 8109,128 секунды с момента запуска JVM и занял 0,04 секунды
Майкл Джозеф
источник
8
просто небольшой комментарий, значение между '()' не является максимальным размером, навсегда, это максимальный размер на данный момент. Если GC не смог освободить кучу меньше, тогда для операционной системы потребуется больше места, и это значение будет увеличиваться. Соблюдая, конечно, лимит, определенный на:
-Xmx
@ rafa.ferreira Я думаю, что значение в парантезе, т.е. 1119040K - это зафиксированный размер кучи. Я не думаю, что сборщик мусора где-либо печатает максимальный размер кучи. Ссылка 1 и Ссылка 2
rohitmohta
23

Я просто хотел упомянуть, что подробный журнал GC можно получить с помощью

-XX:+PrintGCDetails 

параметр. Затем вы видите вывод PSYoungGen или PSPermGen, как в ответе.

Также, -Xloggc:gc.logпохоже, генерирует такой же вывод, как, -verbose:gcно вы можете указать выходной файл в первом.

Пример использования:

java -Xloggc:./memory.log -XX:+PrintGCDetails Memory

Чтобы лучше визуализировать данные, вы можете попробовать gcviewer (более свежую версию можно найти на github ).

Позаботьтесь о том, чтобы параметры были записаны правильно, я забыл "+", и мой JBoss не запускался без сообщения об ошибке!

Андрей
источник
3
Обратите внимание, что gc.log будет перезаписан при перезапуске java (например, если вы перезапустите свой tomcat, потому что у него были проблемы с памятью, и вы хотели бы увидеть этот gc.log). Или, по крайней мере, будет, если вы повернете журналы GC. Есть много других опций, управляющих ведением журнала gc. См. Oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html . В частности, рассмотрим-XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<some number of files> -XX:GCLogFileSize=<some size> -XX:+PrintTenuringDistribution
Дэн Приттс