Scala 和进程中的内存泄漏

2022-09-04 04:41:22

我在Scala中有一个系统,有很多并发线程和系统调用。此系统存在一些问题,因为内存使用量随着时间的推移而增加。

下面的图像显示了一天的内存使用情况。当它达到极限时,该过程关闭,我放了一只看门狗再次恢复它。inserir a descrição da imagem aqui

我定期运行该命令

jcmd <pid> GC.run

这使得内存增长缓慢,但泄漏仍然发生。

我用jvisualvm进行了分析,比较了不同的时刻,40分钟的增量。下面的图像显示了这两个时刻之间的比较。请注意,包中某些类(如 、 、 和 ) 和许多类的实例有所增加。ConcurrentHashMap$HashEntrySNodeWeakReferencechar[]Stringscala.collection.concurrent

memory leaked ojects

什么可能导致内存泄漏?

编辑1:调查JVisualVM,我注意到TryMap中的CNode和INode类的对象,这些类在sbt中实例化。TrapExit$App 类。下面是对象层次结构图:

object hierarchy


答案 1

首先在应用程序由于内存不足问题而崩溃时捕获堆转储。启动 jvm 时添加以下标志

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

接下来,您需要分析堆转储以找出内存泄漏的来源。我建议使用Eclipse MAT。泄漏嫌疑人报告应该让您了解哪些对象实际上导致了泄漏。


答案 2

没有看到实现,很难说。你的帖子的标题表明Scala中存在内存泄漏,但是你有没有检查你的实现与释放对象的问题?

您是否检查了以下内容:

  • 你有没有限制演员的数量?
  • 是否为系统调用设置了超时?
  • 是否允许在执行任务时从堆中删除执行组件?
  • 你有没有数过有多少演员可以融入你的记忆,或者你只是在创造“数百个演员”,希望jvm知道“该做什么”

我想说的是,也许你用完了内存,因为你只是创建了许多后来没有释放的对象,因为它们要么仍在执行任务(没有超时),要么你已经创建了许多对象。

也许您需要将应用程序扩展到多个 jvm?你使用多少个jvm?