OutOfMemory в течение дня после обновления до 2.2.x

#orientdb #orientdb2.2

#orientdb #orientdb2.2

Вопрос:

Мы использовали 2.1.7 и периодически получали OutOfMemory в нашем клиентском приложении и на сервере OrientDB (примерно раз в два месяца). Итак, мы недавно обновили OrientDB с 2.1.7 до 2.2.11. После обновления я получаю OutOfMemory в течение дня в клиентском приложении, которое запрашивает данные из OrientDB.

В куче данных имеется 17 014 экземпляров OSBTreeCollectionManagerRemote и OStorageRemoteAsynchEventListener, что соответствует 95% общей памяти.

Подозревается проблема с памятью скриншот

В рамках обновления Java также была обновлена до 8.

Параметры JVM клиента (tomcat):

 -Xmx2048m -XX:MaxPermSize=512m -XX:MaxDirectMemorySize=2048m -XX: UseParallelOldGC -XX: HeapDumpOnOutOfMemoryError -XX: CMSClassUnloadingEnabled 
  

Я пробовал с пулом подключений к графу и без него, результаты те же.

Может кто-нибудь дать больше информации о том, как решить эту проблему. Я могу поделиться heapdump, если кому-то интересно.

Ответ №1:

вы используете сборщик пропускной способности (ParallelGC), и вы также включаете ParallelOld, поэтому -XX: CMSClassUnloadingEnabled он не используется (потому что это флаг, который будет использоваться с сборщиком ConcurrentMarkSweep, для выгрузки классов из постоянного / метапространства при запуске простой фазы CMS, вместо ожидания нежелательного FullGC)

Пожалуйста, опишите ваш клиентский компьютер, какую ОС, сколько свободной оперативной памяти, сколько процессоров / ядер, сколько Java-процессов запущено на клиентском компьютере?
Помните, что java никогда не следует заменять.

Вместо того, чтобы собирать список огромного и статического дампа кучи, пожалуйста, начните с отслеживания динамического поведения вашего сборщика, используя параметры PrintGC, и, если вы подозреваете утечку, проверьте увеличившееся количество экземпляров, печатающих ascii-гистограммы с помощью jmap -histo:live (который выполняет FullGC перед сбором гистограммы)

ParallelGC работает с полным GC в старом поколении, так что это ожидаемое поведение.

Какую исходную память вы получаете? Это в куче или постоянно или напрямую? Я полагаю, в куче, из-за ваших флагов.

Попытайтесь понять, какой сегмент заполнен, и увеличьте его до предела вашей чистой машины; Чтобы сгенерировать gc.log с номером процесса и меткой времени, используйте :
-XX: PrintGCDetails -XX: PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gclog_%p_%t.log

Вы также можете добавить -XX: PrintTenuringDistribution, to see if promotion is done too early, when age of objects is too low. It could be that new size is too small, so should use a bigger new generation with -Xmn

Вы можете понять текущее значение каждого флага XX, используя также -XX: PrintFlagsFinal . Смотрите также http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html

Запустите java 8u102 с текущими размерами поколения и увеличьте их при необходимости :

 -Xms2048m -Xmn768m -Xmx2048m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:MaxDirectMemorySize=2048m -XX: UseParallelOldGC -XX: PrintGCDetails -XX: PrintGCDateStamps -XX: PrintTenuringDistribution -Xloggc:$CATALINA_HOME/logs/gclog_%p_%t.log <br><br>
<br>
For java 7, instead of Metaspace use Permanent: -XX:PermSize=512m -XX:MaxPermSize=512m
  

Предоставьте всю информацию о клиентской машине и gclog, если вам нужна обратная связь.

Если вы самостоятельно выполняете некоторые настройки из gclog и увеличиваете в несколько раз сегмент памяти, который кажется слишком маленьким, но вы продолжаете получать ту же OutOfMemory, то в вашем приложении может произойти утечка памяти, потому что ParallelGC работает с FullGC (поэтому следует очистить все выпущенные объекты / классы/строки)

Комментарии:

1. Спасибо @Claudio-Massi за подробное объяснение. Я попробую их. Сейчас я тестирую приложение с помощью разных алгоритмов GC. Я буду держать в курсе.