Утечка памяти в Scala и процессы

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

На следующем рисунке показано использование памяти в течение одного дня. Когда он доходит до предела, процесс завершается, и я кладу сторожевую собаку, чтобы восстановить его снова. inserir a descrição da imagem aqui

Я периодически запускаю команду

jcmd <pid> GC.run

И это заставляет память медленно увеличиваться, но утечка все еще происходит.

Я проанализировал с помощью jvisualvm, по сравнению с разными моментами времени, с дельтой 40 минут. На рисунке ниже показано сравнение этих двух моментов времени. Обратите внимание, что для экземпляров некоторых классов, таких как ConcurrentHashMap$HashEntry, SNode, WeakReference, char[] и String, и для многих классов в пакете scala.collection.concurrent есть увеличение.

memory leaked ojects

Что может вызвать утечку памяти?

Изменить 1: Исследуя JVisualVM, я заметил объект классов CNode и INode, которые находятся в TriedMap, который встроен в класс sbt.TrapExit $App. Вот цифра иерархии объектов:

object hierarchy

Ответ 1

Сначала запишите сброс кучи, когда ваше приложение выйдет из строя из-за проблемы с памятью. Добавьте следующие флаги при запуске jvm

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump

Затем вам нужно проанализировать кучу кучи, чтобы выяснить источник утечки памяти. Я рекомендую использовать Eclipse MAT. Отчет "Утечка подозреваемых" должен дать вам представление о том, какие объекты фактически вызывают утечку.

Ответ 2

Не видя реализации, трудно сказать. Заголовок вашего сообщения предполагает, что в Scala есть утечка памяти, но вы проверили свою реализацию против проблем с выпуском объектов?

Вы проверили следующее:

  • Вы ограничиваете число участников?
  • Вы устанавливаете тайм-ауты для системных вызовов?
  • Вы позволяете актерам удаляться из кучи, когда они выполняют свои задачи?
  • Вы подсчитали, сколько актеров может вписаться в вашу память, или вы просто создаете "сотни актеров" с надеждой на то, что jvm будет знать "что делать".

То, что я пытаюсь сказать, состоит в том, что, может быть, у вас закончилась нехватка памяти, потому что вы просто создаете для многих объектов, которые позже не выпущены, потому что либо они все еще выполняют свои задачи (без тайм-аута), либо вы создали для многих из их.

Возможно, вам нужно масштабировать приложение до многих jvms? Сколько jvms вы используете?