Утечка собственной памяти Java с G1 и огромной памятью

В настоящее время у нас есть проблемы с утечкой собственной памяти Java. Сервер довольно большой (40 процессоров, 128 ГБ памяти). Размер кучи Java составляет 64 ГБ, и мы запускаем приложение с очень интенсивным использованием памяти, считывающее большое количество данных в строки с примерно 400 потоками и выбрасывающее их из памяти через несколько минут.

Таким образом, куча заполняется очень быстро, но содержимое кучи устаревает и может быть очень быстро собрано. Таким образом, мы должны использовать G1, чтобы не было перерывов STW в течение нескольких минут.

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

Я много читал об утечках памяти в java, в том числе о проблеме glibc с max. арены (у нас есть wheezy с glibc 2.13, поэтому здесь невозможно исправить, установив MALLOC_ARENA_MAX=1 или 4 без обновления дистрибутива).

Итак, мы попробовали jemalloc, который дал нам графики для:

inuse-space: inuse-space и

используемые объекты: inuse-objects.

Я не понимаю, в чем здесь проблема, у кого-нибудь есть идеи?

Если я установлю MALLOC_CONF="narenas:1" для jemalloc в качестве параметра среды для процесса tomcat, выполняющего наше приложение, может ли он все равно каким-то образом использовать версию glibc malloc?

Это наша установка G1, может здесь какая-то проблема?

-XX:+UseCompressedOops
-XX:+UseNUMA
-XX:NewSize=6000m
-XX:MaxNewSize=6000m
-XX:NewRatio=3
-XX:SurvivorRatio=1
-XX:InitiatingHeapOccupancyPercent=55
-XX:MaxGCPauseMillis=1000
-XX:PermSize=64m
-XX:MaxPermSize=128m
-XX:+PrintCommandLineFlags
-XX:+PrintFlagsFinal
-XX:+PrintGC
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintTenuringDistribution
-XX:-UseAdaptiveSizePolicy
-XX:+UseG1GC
-XX:MaxDirectMemorySize=2g
-Xms65536m
-Xmx65536m

Спасибо за вашу помощь!


person codediver_okay    schedule 04.08.2017    source источник
comment
Было бы очень сложно анализировать этот вопрос, рассматривая его с помощью оптики памяти. Я бы посоветовал отслеживать процесс с помощью таких инструментов, как Dynatrace, чтобы лучше понять распределение памяти, пропускную способность GC и использование ЦП.   -  person Armaiti    schedule 04.08.2017
comment
Сегодня я изолировал утечку собственной памяти G1, которая происходила только при большой нагрузке и частом использовании System.gc(). Я использовал XCode в OS X, чтобы сначала увидеть, что просочившиеся данные в собственной куче были миллионами и миллионами 32-байтных malloc, а затем я использовал dtrace, чтобы определить, что подавляющее большинство этих 32-байтовых malloc происходит из G1.   -  person Reuben Scratton    schedule 30.08.2017


Ответы (1)


Мы никогда не вызывали System.gc() явно, а между тем перестали использовать G1, не указывая ничего, кроме xms и xmx.

Поэтому сейчас используется почти все 128G для кучи. Использование памяти процессом java велико, но постоянно в течение нескольких недель. Я уверен, что это какая-то проблема G1 или, по крайней мере, общая проблема GC. Единственным недостатком этого «решения» являются высокие паузы GC, но они уменьшились с 90 с до примерно 1-5 с с увеличением кучи, что нормально для теста, который мы проводим с нашими серверами.

До этого я экспериментировал с параметрами -XX:ParallelGcThreads, которые существенно влияли на скорость утечки памяти при уменьшении с 28 (по умолчанию для 40 процессоров) до 1. Графики памяти выглядели как веер, использующий разные значения для разных экземпляров. ...

введите здесь описание изображения

person codediver_okay    schedule 01.09.2017