#java #garbage-collection #jvm
#java #сборка мусора #jvm
Вопрос:
на одном из наших серверов сборке мусора потребовалось почти три часа, чтобы попытаться удалить (успешно) 1,2 ГБ кучи памяти. С 1,4 ГБ до 200 МБ.
В течение этого времени загрузка процессора была высокой, почти 80-100%. В чем может быть причина? У нас есть 4 таких сервера с одинаковой конфигурацией (настройки JVM, конфигурация сервера, оборудование, сеть), предполагая, что никто не вносил в нее никаких изменений, что может быть причиной того, что конкретный сервер выполнял сборку 3 часа.
Все остальные серверы тратили всего 5-10 минут на каждое действие GC.
Любезно приложил график из HP BAC для удобства ознакомления. Показывает время, когда, я полагаю, GC запустился, и когда GC остановился.
(Как указывает Стивен для более убедительных выводов) Предоставление этой информации, когда администратор сервера свяжется со мной:
- Точная версия JVM, которую вы используете. (Стандартная Java SE 1.4.2)
- Параметры JVM. (Готовится)
- Подробная информация о базе веб-контейнера / сервера. (Готовится)
- Информация о том, что делает служба. Любые соответствующие подсказки из файлов журнала сервера / службы (поступают)
- Какие-либо соответствующие шаблоны в журналах запросов (поступают)
- GC регистрирует время события. (Если в данный момент у вас не включено ведение журнала GC, возможно, потребуется включить его и подождать, пока проблема не повторится.) (Готовится)
Комментарии:
1. Я думаю, они не шутили, когда сказали, что время динамического выделения памяти неограниченно… (Кстати, что означает BAC? Я на секунду запутался, подумал, что это означает что-то несвязанное, lol.)
2. Привет, Мехрдад, я думаю, это расшифровывается как Business Activity Center.
3. Привет, Мехрдад, что ты подразумеваешь под «динамическим выделением памяти неограниченно», ты имеешь в виду освобождение? Поскольку GC выполняет очистку .. спасибо.
4. @Chin: Ха-ха, хорошо. 🙂 И нет, я имел в виду выделение (хотя это относится и к освобождению), потому что в конечном итоге обычно именно выделения вызывают освобождение.
5. @Chin: это только частичная информация о версии. Полная информация о версии включает номер исправления, платформу операционной системы и является ли она 32-разрядной или 64-разрядной. (Хотя я думаю, что это может быть только 32-разрядная версия для Java 1.4.2.)
Ответ №1:
Здесь не так много данных для работы, но моя догадка: вы меняете местами. Единственный раз, когда мы видим, что время GC настолько велико, — это когда вы перегружаете поле и оно выполняет подкачку на диск. Это может привести к снижению производительности на порядок (или более).
Вам нужно собрать статистику обмена ОС (и, возможно, гипервизора, если это применимо), чтобы доказать или опровергнуть эту теорию.
(Я знаю, что процессорное время выше, чем я ожидал при замене, но вы никогда не знаете.)
Также было бы полезно, если бы вы опубликовали конфигурацию оборудования, информацию о «java -версии» и аргументы командной строки JVM (например: -Xmx и -Xms), чтобы помочь сузить то, что вы действительно используете.
Комментарии:
1. Привет, Грей, спасибо за ваши комментарии, я опубликую конфигурацию оборудования через некоторое время (может быть, от нескольких дней до недели, мне нужно связаться с командой сервера, чтобы получить эти данные). Но когда вы ранее упомянули о замене, вы имели в виду замену страниц между памятью и диском? Почему это происходит для JVM? — могла ли JVM пассивировать неиспользуемые объекты на дисках и после этого выполнять замену?
2. Правильно, да, я имею в виду замену памяти страниц на / с диска. Это может произойти по нескольким причинам: ваш ящик перегружен памятью, ваш -Xmx слишком велик для вашего ящика, у вас утечка встроенной памяти и т.д..
3. В ОС должно быть больше оперативной памяти, чем выделено для кучи JVM (-Xmx).
4. 1 — хорошая теория. В Unix / Linux это будет проявляться как высокая скорость обмена при запуске
vmstat 5
и т.д.
Ответ №2:
Вы не предоставляете много информации, но возможными причинами могут быть:
-
Ошибки в вашем приложении; например, утечка памяти с некоторыми довольно специфическими характеристиками или задача, у которой постоянно заканчивалась память, а затем перезапускалась.
-
Случайная или преднамеренная атака типа «отказ в обслуживании»; например, какой-то клиент, который продолжает повторять запрос чрезмерного размера с параметрами, которые каждый раз уменьшают «размер проблемы».
-
Один чрезвычайно длительный запрос с определенными характеристиками.
-
Сбой — см. Ответ @Trent Gray-Donald’s. (Если у вас избыточно выделенная память, то алгоритмы GC, которые предполагают просмотр множества объектов, случайным образом разбросанных по множеству страниц, с высокой вероятностью спровоцируют перегрузку. Я просто не уверен, что это приведет к постепенному снижению использования кучи, как вы видите.)
-
Патологическая комбинация настроек JVM.
-
Ошибка в сборщике мусора в конкретной используемой вами JVM.
-
Некоторая комбинация из вышеперечисленных.
Это проблема такого рода, которая требует заключения контракта на поддержку Oracle / Java.
Следующая информация может помочь диагностировать это:
- Точная версия JVM, которую вы используете.
- Параметры JVM.
- Подробная информация о базе веб-контейнера / сервера.
- Информация о том, что делает служба.
- Любые соответствующие подсказки из файлов журнала сервера / службы
- Какие-либо соответствующие шаблоны в журналах запросов
- GC регистрирует время события. (Если в данный момент у вас не включено ведение журнала GC, возможно, потребуется включить его и подождать, пока проблема не повторится.)