Я создал тестовое приложение (с 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 выполняется быстрее. Спасибо всем за разъяснение, почему это сделано так, как есть.
-XX:+PrintFlagsFinal
в качестве последнего флага виртуальной машины, запишите выходные данные и запустите diff. 32-битные и 64-битные виртуальные машины, скорее всего, ведут себя совершенно по-разному, потому что первые, скорее всего, будут классифицироваться как машины клиентского класса. Количество потоков также может иметь значение. - person the8472   schedule 08.06.2015+UseCompressedOops
должно привести к одинаковой упаковке для 32-битных и 64-битных систем. возможно, кроме выравнивания объектов - person the8472   schedule 08.06.2015