Java Scala和进程中的内存泄漏

Java Scala和进程中的内存泄漏,java,scala,memory,memory-leaks,Java,Scala,Memory,Memory Leaks,我有一个Scala系统,有很多并发线程和系统调用。这个系统有一些问题,因为内存使用量随着时间的推移而增加 下图显示了一天的内存使用情况。当它达到极限时,进程关闭,我让一只看门狗再次恢复它 我定期运行命令 jcmd <pid> GC.run jcmd GC.run 这使得内存增长缓慢,但仍然会发生泄漏 我用jvisualvm进行了分析,与时间上的不同时刻进行了比较,时间差为40分钟。下图显示了这两个时刻在时间上的比较。请注意,一些类的实例(如ConcurrentHashMap$Ha

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

下图显示了一天的内存使用情况。当它达到极限时,进程关闭,我让一只看门狗再次恢复它

我定期运行命令

jcmd <pid> GC.run
jcmd GC.run
这使得内存增长缓慢,但仍然会发生泄漏

我用jvisualvm进行了分析,与时间上的不同时刻进行了比较,时间差为40分钟。下图显示了这两个时刻在时间上的比较。请注意,一些类的实例(如
ConcurrentHashMap$HashEntry
SNode
WeakReference
char[]
String
以及包
scala.collection.concurrent
中的许多类)都有所增加

什么可能导致内存泄漏

编辑1: 在研究JVisualVM时,我注意到TriedMap中的CNode和INode类的对象,它在sbt.TrapExit$App类中实例化。以下是对象层次结构图:


当应用程序因内存不足而崩溃时,首先捕获堆转储。启动jvm时添加以下标志

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

接下来,您需要分析堆转储以找出内存泄漏的来源。我建议使用。该报告应该让您了解到底是什么对象导致了泄漏。

如果没有看到实现,很难说。你文章的标题表明Scala中存在内存泄漏,但是你有没有检查过你的实现是否存在释放对象的问题

您是否检查了以下内容:

  • 你有限制演员的数量吗
  • 你为系统调用设置了超时吗
  • 当参与者执行其任务时,是否允许将其从堆中移除
  • 您是否计算了内存中可以容纳多少参与者,或者您只是创建了“数百个参与者”,希望jvm知道“该做什么”
我想说的是,可能你的内存不足,因为你只是创建了许多对象,而这些对象后来没有被释放,因为它们仍然在执行任务(没有超时),或者你已经创建了许多对象


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

我看到list.toStream.map,但是scala.collection.concurrent从何而来?当你说“很多线程”时,你的意思是你“foo.par”很多吗?我不是以平行收藏专家的身份来提问。你在显式地使用TrieMap吗?很多线程,我的意思是有数百个参与者,每个参与者都进行系统调用,并创建一些异步执行任务的未来。我没有明确使用TrieMap。您有更新的答案吗?我也有类似的问题。希望任何人都能找出根本原因。提前谢谢。有了堆差异,我已经知道泄漏的来源了。ConcurrentHashMap$HashEntry的数量正在增加。但是我在代码中没有使用这些对象,所以它看起来像scala或JVM中的某些东西。您可能没有直接实例化这些对象,但它确实发生了。因此,您需要追溯到创建这些对象的时间/地点。所以谁创建了CNode实例等等。一些对象保留了对CNode的引用,防止它(及其引用的对象)被垃圾收集。EclipseMat有这样一个视图——它应该给您提供一些信息。