使用ForkJoinTask []和ForkJoinPool内存泄漏Play Framework中的WorkQueue(Scala)

时间:2015-01-16 12:51:37

标签: scala memory-leaks playframework-2.0 akka

我在Scala v2.11.4上编写了一个Play Framework v2.3.7中的应用程序。它在服务器上运行,每周崩溃一次,出现OutOfMemoryError异常:超出GC开销限制。我试图弄清楚那里有什么问题。我制作了内存转储并制作了所有使用过的类的直方图(我使用了jmap -histo)。我发现了非常奇怪的结果:

Object Histogram:

num       #instances    #bytes  Class description
--------------------------------------------------------------------------
1:              24023   787570032       scala.concurrent.forkjoin.ForkJoinTask[]
2:              96965   12420368        * MethodKlass
3:              96965   11250824        * ConstMethodKlass
4:              8424    8652552 * ConstantPoolKlass
5:              8424    7547640 * InstanceKlassKlass
6:              61739   5531288 char[]
7:              7527    4799776 * ConstantPoolCacheKlass
8:              24024   4612608 scala.concurrent.forkjoin.ForkJoinPool$WorkQueue
9:              27289   3543672 byte[]
10:             23190   2597280 scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$2
11:             63921   2045472 java.util.concurrent.ConcurrentHashMap$HashEntry
12:             3735    1470112 * MethodDataKlass
13:             42877   1029048 scala.collection.immutable.$colon$colon
14:             8834    1023064 java.lang.Class

因此,有很多ForkJoinTask[]ForkJoinPool$WorkQueue的实例。所以,我假设,它是我的所有异步调用和应用程序线程的队列和任务。而且我认为,从理论上讲,它们应该在完成后立即删除。

这个问题的可能原因是什么?也许我错过了配置ExecutionContext?以前有人遇到过这个问题吗?

2 个答案:

答案 0 :(得分:0)

您使用的是哪种情境?根据{{​​3}},您应该使用

play.api.libs.concurrent.Execution.Implicits.defaultContext 

而不是默认

scala.concurrent.ExecutionContext.Implicits.global

请参阅此documentation进行说明。

答案 1 :(得分:0)

使用最新版本的“scala-reflect”库(稍后版本2.11.6)解决了该问题:

val scalaV = "2.11.6"

scalaVersion := scalaV

libraryDependencies ++= Seq(
  "org.scala-lang" % "scala-reflect" % scalaV
)

以下是错误说明:https://issues.scala-lang.org/browse/SI-8946