#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. Я буду держать в курсе.