在类中包装akka actor会导致内存泄漏吗?

时间:2014-04-14 17:18:29

标签: scala memory-leaks out-of-memory akka actor

我有一个相当基本的包装类围绕scala akka actorRef。基本上该类有一个作为actorRef的字段,并公开了许多方法,这些方法可以告诉"给actorRef的特定消息。以这种方式,我可以遵循指定API并避免暴露tell或消息类。我的程序中遇到了内存泄漏问题,我想知道围绕akka actor的包装是否导致问题。我在下面写了这个模拟来测试我的理论。

import akka.actor.{ActorSystem, ActorRef, PoisonPill}
import akka.actor.ActorDSL._

implicit val as = ActorSystem()

def createMemoryActor(): ActorRef = actor(new Act {
  Array.fill(99999999)(1.0) // Just to take up memory
  become {
    case _ => print("testing memory leaks")
  }
})

val memoryActor = createMemoryActor() // memory usage jumps up

memoryActor ! PoisonPill
System.gc() // memory usage goes back down

case class ActorWrapper() {
  val memoryActor = createMemoryActor()
}

def doNothing(): Unit = {
  val shouldGetGCed = ActorWrapper()
  ()
}

doNothing() // memory usage jumps up
System.gc() // memory usage goes back down

我在scala repl中运行上面的代码并运行jvisualvm来分析内存使用情况。似乎" shouldGetGCed"引用收集车库,其actorRef字段(占用内存)也被垃圾收集。总是这样,还是我错过了什么?任何人都有任何最佳实践来包装演员以遵守特定的API吗?

1 个答案:

答案 0 :(得分:6)

每个启动的actor最终都必须停止,直到发生这种情况,它才会占用内存。在您的示例中,您需要例如shouldGetGCed.memoryActor ! PoisonPill。没有针对actor的自动垃圾收集,因为它们本质上是分布式实体,并且JVM不支持分布式GC。