Чрезмерно агрессивный сборщик мусора, доминирующий процессор - PullRequest
0 голосов
/ 22 мая 2018

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

2018-05-21T20:08:41.136-0400: 19979.368: [GC (Allocation Failure) [PSYoungGen: 71364K->10997K(73728K)] 303964K->243661K(466944K), 0.0165899 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
2018-05-21T20:09:01.212-0400: 19999.444: [GC (Allocation Failure) [PSYoungGen: 71413K->11065K(73728K)] 304077K->243865K(466944K), 0.0121248 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
2018-05-21T20:09:30.450-0400: 20028.682: [GC (Allocation Failure) [PSYoungGen: 71481K->12550K(73728K)] 304281K->245422K(466944K), 0.0133476 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
2018-05-21T20:09:50.492-0400: 20048.723: [GC (Allocation Failure) [PSYoungGen: 72966K->10454K(73728K)] 305838K->243374K(466944K), 0.0141533 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 

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

2018-05-21T20:10:12.104-0400: 20070.335: [GC (Allocation Failure) [PSYoungGen: 70870K->10356K(73728K)] 303790K->243340K(466944K), 0.0193899 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
2018-05-21T20:10:12.222-0400: 20070.453: [GC (Allocation Failure) [PSYoungGen: 70772K->2080K(72704K)] 303756K->235288K(465920K), 0.0090667 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
2018-05-21T20:10:12.413-0400: 20070.645: [GC (Allocation Failure) [PSYoungGen: 61472K->1936K(73728K)] 294680K->235256K(466944K), 0.0081242 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2018-05-21T20:10:12.519-0400: 20070.751: [GC (Allocation Failure) [PSYoungGen: 61328K->1585K(81408K)] 294648K->235248K(474624K), 0.0053709 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2018-05-21T20:10:12.582-0400: 20070.813: [GC (Allocation Failure) [PSYoungGen: 67633K->1313K(82432K)] 301296K->235240K(475648K), 0.0080559 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
2018-05-21T20:10:12.647-0400: 20070.878: [GC (Allocation Failure) [PSYoungGen: 67361K->1121K(92160K)] 301288K->235264K(485376K), 0.0052482 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
2018-05-21T20:10:12.718-0400: 20070.950: [GC (Allocation Failure) [PSYoungGen: 76897K->801K(92672K)] 311040K->235256K(485888K), 0.0071820 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2018-05-21T20:10:12.792-0400: 20071.024: [GC (Allocation Failure) [PSYoungGen: 76577K->641K(105472K)] 311032K->235232K(498688K), 0.0070387 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
2018-05-21T20:10:12.878-0400: 20071.109: [GC (Allocation Failure) [PSYoungGen: 89217K->32K(105472K)] 323808K->235249K(498688K), 0.0084592 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2018-05-21T20:10:12.962-0400: 20071.194: [GC (Allocation Failure) [PSYoungGen: 88608K->64K(119296K)] 323825K->235289K(512512K), 0.0066050 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

Пока процессор задействован, мое приложение не работает должным образом.Сервер имеет два ЦП, но JVM, похоже, использует только один из них, при этом pidstat сообщает о среднем использовании чуть более 100%.

Что меня больше всего удивляет в этом, так это то, что молодое поколение склоняется кнебольшая часть пространства, выделенного для него и хранящегося там, не может превысить 1 Мб после сборки мусора.

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

Моя текущая конфигурация для JVM:

-XX:InitialHeapSize=268435456 
-XX:MaxHeapSize=2147483648 
-XX:+PrintGC 
-XX:+PrintGCDateStamps 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops 
-XX:+UseParallelGC 

1 Ответ

0 голосов
/ 22 мая 2018

Вы описываете симптомы сборки мусора "спираль смерти".

В основном, если у вас есть куча, где пространство, занимаемое достижимыми объектами, постоянно стремится вверх, и все больше и больше времени тратится на работу сборщика мусора.В конце концов, куча либо полностью заполнится, либо будет превышен предел накладных расходов GC.В любом случае будет выброшено OOME.

Существует три основных подхода:

  1. Периодически перезапускать приложение.
  2. Увеличение размера кучи.
  3. Выясните, почему ваше приложение использует все больше и больше кучи.Как правило, возникает утечка памяти какого-то рода.

Только третий подход действительно решает проблему. Остальные решения являются "вспомогательными".


ХотяТаким образом, процессор включен, мое приложение не работает должным образом.Сервер имеет два ЦП, но JVM, похоже, использует только один из них, при этом pidstat сообщает о среднем использовании чуть более 100%.

Если на ГХ слишком большое давление (например, из-за«почти полная» куча), тогда вы, вероятно, обнаружите, что он должен вернуться к неэргономичным режимам работы.Например, возможно, он решил создать только один фоновый поток GC при запуске JVM, это нормально, но при экстремальной загрузке GC этот поток достигает 100%, и потоки вашего приложения затем блокируются.

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

...