JVM работает по-разному с одинаковыми флагами

Я создал тестовое приложение (с Sheduler внутри, которое запускается каждые 20 мс, есть чтение/запись в БД) и развернул его на сервере Glassfish на двух разных ПК. Оба имеют одинаковый (копировать с одного ПК на другой) сервер Glassfish (оба также имеют последнюю версию JAVA) со следующими флагами: -XX:+DisableExplicitGC, XX:MaxGCPauseMillis=200, -Xmx512m, -Xms512m, -XX:+UseCompressedClassPointers -XX :+UseCompressedOops -XX:+UseG1GC, -сервер...

Первый ПК имеет 8 ГБ оперативной памяти, процессор i5 (2,5 ГГц) с 64-битной ОС WIN 8.1.

Вот графическое представление журнала GC первого ПК (через 30 часов): введите здесь описание изображения

Как вы можете видеть, производительность GC составляет около 12000 МБ/с, пропускная способность составляет 99,93%, небольшие паузы GC составляют около 20 мс и происходят каждые 30 секунд. В это время не было крупного GC (но это произошло через 8 часов). За первые 30 часов старое поколение увеличилось с 90 МБ до 160 МБ.

Второй ПК имеет 1 ГБ оперативной памяти, процессор Athlon 64 X2 (двухъядерный) и WIN XP 32bit. Вот графическое представление журнала GC второго ПК (через 30 часов): введите здесь описание изображения

Как вы можете видеть, производительность GC составляет около 4000 МБ/с, пропускная способность составляет 99,91%, небольшие паузы GC составляют около 100 мс и происходят каждые 50 секунд. В это время не было серьезного GC (его все еще не произошло через 4 дня). За первые 30 часов старое поколение увеличилось примерно с 70 МБ до 75 МБ.

У меня вопрос: почему продвижение к старому поколению во втором случае намного меньше, чем в первом? Это означает, что основной сборщик мусора не будет запускаться какое-то время (возможно, никогда), когда основной сборщик мусора в первом случае был запущен через 40 часов. Приложение делает одно и то же в обоих случаях, поэтому я не понимаю, почему JVM работает так по-разному с одинаковыми флагами. Я не знаю, каковы преимущества в первом случае (большее продвижение объекта к старому поколению), если это означает, что основной GC должен происходить, когда во втором случае основной GC не должен происходить. Какая польза от перехода от оставшегося пространства к старому поколению, если приложение на обоих серверах выполняется с одинаковой скоростью (запись в БД каждые 20 мс, а затем чтение из одного и того же блока БД). Также малые GC во втором случае встречаются реже (50 секунд), чем в первом случае (30 секунд). Я ожидаю, что лучший ПК будет иметь гораздо лучшие результаты, но теперь я даже не знаю, какой из них лучше ... Единственное главное преимущество первого случая - более высокая скорость производительности GC, поэтому мелкий GC выполняется быстрее. Спасибо всем за разъяснение, почему это сделано так, как есть.


person user4341206    schedule 08.06.2015    source источник
comment
Какие точные версии Java на каждом?   -  person Chris Dennett    schedule 08.06.2015
comment
На обоих установлена ​​последняя версия JAVA (8u45), на первом 64-битная, а на втором 32-битная.   -  person user4341206    schedule 08.06.2015
comment
добавьте -XX:+PrintFlagsFinal в качестве последнего флага виртуальной машины, запишите выходные данные и запустите diff. 32-битные и 64-битные виртуальные машины, скорее всего, ведут себя совершенно по-разному, потому что первые, скорее всего, будут классифицироваться как машины клиентского класса. Количество потоков также может иметь значение.   -  person the8472    schedule 08.06.2015
comment
То, что все, что вы на самом деле настроили, одинаково, не означает, что под капотом нет вещей, которые по-разному работают на 64-битных и 32-битных платформах. Кроме того, типы данных Java не обязательно упаковываются. В зависимости от того, что вы делаете, многие ваши данные могут занимать в два раза больше места на 64-битной машине...   -  person Affe    schedule 08.06.2015
comment
+UseCompressedOops должно привести к одинаковой упаковке для 32-битных и 64-битных систем. возможно, кроме выравнивания объектов   -  person the8472    schedule 08.06.2015
comment
Или, проще говоря, неудивительно, что приложение, которому требуется столько памяти, сколько может быть доступно на 32-битной платформе, будет работать лучше на 32-битной платформе.   -  person Affe    schedule 08.06.2015
comment
мне кажется, что эти рассуждения покоятся на шаткой почве. особенно учитывая, что он испытывает более низкую пропускную способность GC в 32-битной системе.   -  person the8472    schedule 08.06.2015
comment
Вы уверены, что используете ту же версию Java? Java 8 не поддерживает Windows XP: java.com/en/download/help/sysreq. XML   -  person Svetlin Zarev    schedule 08.06.2015
comment
Да, я использую ту же версию Java (она была установлена, хотя официально не поддерживается).   -  person user4341206    schedule 08.06.2015
comment
Упс сжимает указатели, а не данные. Если для выполнения одной и той же задачи используется меньше памяти, конечно, пропускная способность ниже, меньше нужно собирать.   -  person Affe    schedule 08.06.2015


Ответы (1)


Я ожидал, что чем лучший ПК будет иметь гораздо лучшие результаты, но теперь я даже не знаю, какой из них лучше...

Лучше субъективно. В зависимости от того, нужна ли вам пропускная способность (доля циклов ЦП, затраченная на сборку мусора), устойчивые скорости распределения, малое время паузы или малая занимаемая площадь. Как правило, между этими целями есть компромисс.

G1GC — сложный, самонастраивающийся зверь, который ведет себя по-разному в разных обстоятельствах. Итак, если на самом деле нет проблемного поведения, которого вы хотите избежать, в чем проблема? Он просто выполняет свою работу по-другому.

Как упоминалось в комментариях, если вы просто хотите удовлетворить свое любопытство, вы можете сравнить флаги VM, добавив -XX:+PrintFlagsFinal к параметрам и запустив diff. Вероятно, они сильно отличаются, потому что 32-битные и 64-битные системы имеют разные значения по умолчанию.

person the8472    schedule 08.06.2015
comment
Я сравню флаги, используя -XX:+PrintFlagsFinal, как только у меня будет доступ к обоим компьютерам. У меня есть один глупый вопрос: отображались ли эти флаги, если я запускаю сервер Glassfish (может быть, в журнале домена при запуске или где-то еще)? Мне было просто любопытно, почему такая разница, я всегда думал, что тот, у кого менее крупный (или полный) GC, лучше, чем тот, у которого их больше... - person user4341206; 08.06.2015
comment
обычно это выводится на стандартный вывод. Я не знаю, что делает стеклянная рыба, может быть, она перенаправляет все в лог-файл. но вам не нужно запускать стеклянную рыбу только для печати параметров виртуальной машины, вы можете просто использовать те же параметры и вызывать их вручную из cmd - person the8472; 08.06.2015
comment
Спасибо. Существует довольно много различий в флагах (в 64-битной версии для большинства из них установлено значение true или установлены более высокие значения), а некоторые отсутствуют в 32-разрядной версии. - person user4341206; 08.06.2015