Утечка памяти в 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 вы используете?