Интерпретация вывода jstat после настройки размера кучи JVM

Недавно пытаясь увеличить пространство кучи и соотношение размера нового и старого поколения, я вижу сбивающие с толку результаты jstat -gccapacity который показывает гораздо меньшие мощности, чем я ожидал.

JVM (1.5.0_16) запускается с -server -Xms2048m -Xmx2048m -XX:NewRatio=2, Он работает на хосте Solaris 5.10 amd64. Около 10 ГБ свободной памяти. Итак, из того, что я прочитал, JVM должна иметь возможность использовать все 2 ГБ пространства кучи.

наблюдение jstat -gcutil Я наблюдал, как все поколения заполнялись несколько раз, вызывая сборку мусора. Например:

Timestamp         S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
        66150.4   0.00  51.09  56.95  90.33  54.85   6291   58.922     7   22.826   81.748

То, что я думал, заставило бы JVM расширить все поколения до их полного размера. Тем не мение, jstat -gccapacity производит:

 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
700416.0 700416.0  86016.0 1408.0 1408.0  39104.0  1398784.0  1398784.0  1398784.0  1398784.0  16384.0  65536.0  38912.0  38912.0   6338     7

Последующие прогоны показывают изменение значения NGC/S0C/S1C/EC:

 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
700416.0 700416.0  86016.0 1472.0 1472.0  39104.0  1398784.0  1398784.0  1398784.0  1398784.0  16384.0  65536.0  38912.0  38912.0   6380     7
700416.0 700416.0 106496.0 1792.0 1856.0  97024.0  1398784.0  1398784.0  1398784.0  1398784.0  16384.0  65536.0  38912.0  38912.0   6433     7
700416.0 700416.0 106496.0 1792.0 1792.0  96064.0  1398784.0  1398784.0  1398784.0  1398784.0  16384.0  65536.0  38912.0  38912.0   6436     7

Из того, что я понимаю, цифры мощности - это общий размер генерации, а цифры использования показывают распределение внутри генерации. Таким образом, приведенный выше результат говорит мне о том, что объединенные новые минимальные и максимальные емкости gen (NGCMN/MGCMX) составляют 684 МБ, а старые минимальные и максимальные емкости - 1366 МБ (OGCMN/OGCMX). Что меня смущает, так это возможности новых поколений. Итак, мои вопросы:

  1. Почему EC + S0C + S1C == NGC? (41 920!= 86016)
  2. Почему NGC значительно меньше, чем NGCMN/MGCMX?
    • Это связано с тем, что достигается максимальный размер кучи (что составляет 1488 МБ от NGC+OGC+PGC), если это так, что может вызвать нижний предел? Вся документация, которую я могу найти, говорит, что 64-битная JVM Solaris должна иметь возможность использовать 4 ГБ.
  3. Если достигается максимальный размер кучи, почему новые поколения изменяют свою мощность (либо все увеличиваются, либо все уменьшаются) без изменения старшего поколения для компенсации).

Другие потенциально полезные результаты jstat:

$ jstat -gcnew 20167
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
1536.0 1600.0 1300.3    0.0 13  15 1600.0  82880.0  30892.6   6482   60.540

$ jstat -gcnewcapacity 20167
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC
  700416.0   700416.0   106496.0   1472.0 233472.0 233472.0   1408.0   700288.0    81088.0  6489     7

$ jstat -gcold 20167
   PC       PU        OC          OU       YGC    FGC    FGCT     GCT
 38912.0  21426.5   1398784.0   1375651.6   6503     7   22.826   83.627

$ jstat -gcoldcapacity 20167
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
  1398784.0   1398784.0   1398784.0   1398784.0  6517     7   22.826   83.779

$ jstat -gcpermcapacity 20167
  PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT
   16384.0    65536.0    38912.0    38912.0  6531     7   22.826   83.925

1 ответ

Решение

Оказывается, это намеренное поведение сборщика пропускной способности:

Настройка сборки мусора с помощью виртуальной машины Java[tm] 5.0> 5.2.2.2 Настройка размеров генерации

Статистические данные (например, среднее время паузы), сохраняемые сборщиком, обновляются в конце коллекции. Затем выполняются тесты для определения того, были ли достигнуты цели, и вносятся необходимые корректировки в размер поколения.

Наблюдение за емкостями ГХ, когда JVM находится под пиковой нагрузкой, действительно показывает, что суммарные мощности молодого поколения равны минимальной / максимальной значениям емкости.

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