Молодое поколение крошечно, несмотря на NewRatio=2

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

Варианты JVM: java -Xmx240g -XX:+UseConcMarkSweepGC -XX:NewRatio=2 -XX:+PrintGCTimeStamps -verbose:gc -XX:+PrintGCDetails

В какой-то момент мой журнал GC начинает выглядеть так:

800.020: [GC 800.020: [ParNew: 559514K->257K(629120K), 0.1486790 secs] 95407039K->94847783K(158690816K), 0.1487540 secs] [Times: user=3.34 sys=0.05, real=0.15 secs] 
800.202: [GC 800.202: [ParNew: 559489K->246K(629120K), 0.1665870 secs] 95407015K->94847777K(158690816K), 0.1666610 secs] [Times: user=3.79 sys=0.00, real=0.17 secs] 
800.402: [GC 800.402: [ParNew: 559478K->257K(629120K), 0.1536610 secs] 95407009K->94847788K(158690816K), 0.1537290 secs] [Times: user=3.48 sys=0.02, real=0.15 secs]

Меня очень смущает тот факт, что размер Young Generation составляет 629120K (=629M), в то время как я ожидаю, что он составит прибл. 1/2 (потому что NewRatio=2) размера заемного поколения, равного 158690816K (=158G). Генерирование заимствованного размера соответствует NewRatio и Xms, как и ожидалось, т.е. составляет 2/3 от общего размера кучи.

Версия JVM: java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

Обновление: я считаю, что на данный момент (800 секунд времени выполнения) программа имеет пиковое использование временного массива. Если программа не выходит за рамки размера молодого поколения 629M, значит ли это, что я должен увеличить NewRatio? Давайте предположим, что я планирую увеличить нагрузку на программу, и я ожидаю, что отношение объема временных массивов к постоянным массивам будет таким же.

Я запускал программу с NewRatio=8 раньше, и журнал gc состоит в основном из таких строк:

800.004: [GC 800.004: [ParNew: 186594K->242K(209664K), 0.1059450 secs] 95345881K->95159529K(126655428K), 0.1060110 secs] [Times: user=2.41 sys=0.00, real=0.10 secs] 
800.122: [GC 800.122: [ParNew: 186610K->221K(209664K), 0.1073210 secs] 95345897K->95159522K(126655428K), 0.1073900 secs] [Times: user=2.37 sys=0.07, real=0.11 secs] 
800.240: [GC 800.240: [ParNew: 186589K->221K(209664K), 0.1026210 secs] 95345890K->95159524K(126655428K), 0.1026870 secs] [Times: user=2.34 sys=0.00, real=0.10 secs] 
800.357: [GC 800.357: [ParNew: 186589K->218K(209664K), 0.1043130 secs] 95345892K->95159527K(126655428K), 0.1043810 secs] [Times: user=2.30 sys=0.07, real=0.10 secs] 

Это заставляет меня думать, что NewRatio в настоящее время оказывает влияние на размер поколения Young, но не должно, потому что в настоящее время поколение Young намного меньше 1/9 размера кучи.

Обновление 2: это огромный научный расчет, и для моего решения требуется до 240 ГБ памяти. Это не утечка памяти, и алгоритм - лучшее, что мне удалось придумать.

2 ответа

Пожалуйста, не могли бы вы попробовать запустить с отключенным AdaptiveSizePolicy, используйте: -XX-UseAdaptiveSizePolicy?

Это должно позволить вам заранее задавать размеры каждой области кучи и отключать динамические изменения их размеров во время выполнения.

Прежде всего, проверьте, что означают флаги -XX:NewRatio и -XX:OldSize JVM?

NewRatio - это отношение молодого поколения к старому поколению (например, значение 2 означает, что максимальный размер старого будет в два раза больше максимального размера молодого, т. Е. Молодой может получить до 1/3 кучи).

и вы увидите, что размер вашего молодого поколения правильный.

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

-Xms240g -Xmx240g -XX:NewSize=120g -XX:MaxNewSize=120g -XX:-UseAdaptiveSizePolicy
Другие вопросы по тегам