【问题标题】:Memory leaking with ForkJoinTask[] and ForkJoinPool$WorkQueue in Play Framework (Scala)Play Framework (Scala) 中的 ForkJoinTask[] 和 ForkJoinPool$WorkQueue 内存泄漏
【发布时间】:2015-03-15 02:00:38
【问题描述】:

我有一个使用 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?以前有人遇到过这个问题吗?

【问题讨论】:

  • 您的特定 ExecutionContext 配置是什么?
  • 我没有做任何额外的配置。将其留空:{}。我想,默认参数应该适合我。
  • 嗯,它们通常是,但我以为你已经定制了它,因为你提到了"Maybe I missconfigured an ExecutionContext?" :S

标签: scala memory-leaks playframework-2.0 akka


【解决方案1】:

使用最新版本的“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

【讨论】:

  • 你确定这个额外的库能解决你的问题吗?我没找到你叫这个图书馆的地方。你能不能给我一些详细的解释。因为目前我也遇到了这个性能问题。谢谢。
  • 好吧,在那个具体情况下,我的应用程序使用了依赖于旧版本 scala-reflect 的库(并且旧版本包含 bug)。所以,当我明确指定应该使用哪个版本的 scala-reflect 时,问题就解决了。
【解决方案2】:

您使用的是哪个上下文?根据documentation,你应该使用

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

而不是默认的

scala.concurrent.ExecutionContext.Implicits.global

请参阅此answer 了解详情。

【讨论】:

  • 我阅读了文档,但没有找到您建议进行此更改的原因。你能给出明确的理由吗?谢谢。
  • 我添加了一个解释的链接。
猜你喜欢
  • 2014-11-08
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多