#java #memory #garbage-collection #websphere #heap-memory
#java #память #сбор мусора #websphere #куча-память
Вопрос:
У нас есть сервер AIX-Websphere java7, который использует очень большой объект таблицы / массива в памяти, обычно размером около 3,1 ГБ. Для этого сервера мы настроили -Xms=3072m и -Xmx=3840m (алгоритм GC = gencon). Он работал нормально, пока однажды внезапно не увеличил время GC с миллисекунд до секунд каждую минуту, согласно Dynatrace.
Огромный объект обычно растет, потому что удалений мало, обновлений нет, но постоянный поток вставок.
Пробуя разные подходы, мы улучшили время GC (опять же с миллисекундами), просто изменив -Xms на 1024m.
Кто-нибудь знает, какой принцип позволяет это улучшение, просто не увеличивая Xms? То, что я прочитал в другом сообщении, было противоположным. То есть оптимальным подходом было бы увеличение Xms или даже сопоставление его с Xmx.
Комментарии:
1. Это 64-разрядная JVM?
2. Да. java версии «1.7.0» Java (TM) SE среда выполнения (сборка pap6470sr9fp30-20160112_01 (SR9 FP30)) IBM J9 VM (сборка 2.6, JRE 1.7.0 AIX ppc64-64 Сжатые ссылки 20151222_283043 (с поддержкой JIT, с поддержкой AOT) J9VM — R26_Java726_SR9_20151222_1626_B283043 JIT — tr. r11_20151209_107111.01 GC — R26_Java726_SR9_20151222_1626_B283043_CMPRSSJ9CL — 20151222_283043) JCL — 20160112_01 на основе Oracle jdk7u95-b13
Ответ №1:
Длительные паузы GC, вероятно, связаны с фрагментацией кучи, требующей уплотнения для размещения некоторого объекта в области владения кучи. Если объект кэша занимает 3,1 ГБ из максимальной кучи 3840m, в куче остается очень мало рабочего пространства для нормального потока выделения и удаления объектов, который происходит при выполнении программ Java. Поскольку объекты Java должны быть размещены в непрерывном пространстве памяти, если выделяется какой-либо объект, для которого в памяти кучи не доступно достаточно большое непрерывное пространство, требуется сжатие. Сжатие — это относительно длительный медленный процесс изменения расположения объектов в куче, чтобы устранить небольшие промежутки между объектами и создать большую непрерывную область для новых выделений (например, дефрагментация жесткого диска в старых системах Windows).
Честно говоря, я довольно удивлен, что конфигурация, подобная описанной вами, когда-либо будет работать хорошо. Помимо упомянутого «объекта кэша» (возможно, это на самом деле набор из множества небольших объектов?) будет базовый набор долгоживущих объектов, реализующих WebSphere runtime, для которых обычно требуется более 100 МБ. И затем в любой системе Java существует постоянный поток создания и удаления объектов (посредством сборки мусора). Типичное эмпирическое правило заключается в том, чтобы размер кучи был таким, чтобы после глобального GC область владения была на 50% свободной — все, что меньше 20% свободного после глобального, приведет к нежелательным накладным расходам GC.
Включено ли у вас подробное ведение журнала GC в этой конфигурации? Это единственный способ узнать, что происходит внутри кучи, и знание этого важно для работоспособности и производительности системы Java. Мы рекомендуем включить ведение журнала GC (добавив -verbose:gc к аргументам JVM ) во всех системах Java, как в производственных, так и в тестовых средах. Накладные расходы на ведение журнала GC в IBM Java очень малы, а диагностическая ценность очень высока.
Что касается того, почему настройка -Xms1024 улучшила производительность, есть несколько возможностей.
Во-первых, возможно, что это изменение на самом деле ничего не исправило. Некоторое время вы не видели длительных пауз GC, затем они появились, теперь они (по крайней мере, временно) исчезли. Автоматическое управление памятью (частью которого является очистка GC) является скорее вероятностной, чем детерминированной функцией, поскольку размещение объектов в куче может меняться в зависимости от случайных изменений, таких как объекты, размещаемые в несколько ином порядке. Если бы я работал с системой, я бы не доверял улучшению, не увидев журналы GC, которые показывают, что все хорошо.
Другая возможность заключается в том, что, если размер кэша сильно меняется с течением времени, так что заполнение кучи сильно меняется, то куча может увеличиваться и уменьшаться больше с настройкой small -Xms. Когда куча сжимается, выполняется сжатие для перемещения живых объектов, распределенных по большому пространству кучи, в новое меньшее пространство, так что небольшая куча будет находиться в непрерывном диапазоне адресов памяти. Сжатие при сжатии кучи обычно происходит в те моменты, когда система не очень занята (вот почему куча довольно пуста) и требуется меньше оперативных данных, поэтому сжатие будет короче и с меньшей вероятностью заметно повлияет на производительность.
В общем, наилучшая производительность GC будет достигнута, если установить -Xms и -Xmx одинаково, потому что тогда изменение размера кучи вообще не происходит. Однако, чтобы узнать, какой подходящий размер, вы должны включить ведение журнала GC и просмотреть журнал, охватывающий неделю или более работы. Размер кучи должен быть таким, чтобы по крайней мере 30% пространства владения оставалось свободным после глобального GC, чтобы время, затрачиваемое на выполнение GC, не было чрезмерным.
Комментарии:
1. Спасибо. Я попытаюсь добавить подробный и изучить его с помощью GCMV, пытаясь следовать строке 30% владения. С другой стороны, я собираюсь изменить сообщение, чтобы заметить, что объект кэша на самом деле не является кэшем (я позволил себе увлечься именем класса), а массивом / таблицей в памяти, поэтому он на самом деле не меняется, а растет (есть несколько удалений, обновления нетно постоянный поток вставок)