AKKA Actor内存泄漏

Memory leak of AKKA Actor

我有一个简单的测试程序可以尝试...

object ActorLeak extends App {
  val system = ActorSystem("ActorLeak")
  val times = 100000000
  for (i <- 1 to times) {
    val myActor = system.actorOf(Props(classOf[TryActor], i), name = s"TryActor-$i")
    //Thread sleep 100
    myActor ! StopCmd
    if (i % 10000 == 0)
      println(s"Completed $i")
  }
  println(s"Creating and stopping $times end.")
  val hookThread = new Thread(new Runnable {
    def run() {
      system.shutdown()
    }
  })
  Runtime.getRuntime.addShutdownHook(hookThread)
}
case object StopCmd
class TryActor(no: Int) extends Actor {
  def receive = {
    case StopCmd => context stop self
  }
}

我发现:有时会出现 OutOfMemoryError,有时会使 JVM 死掉,运行 慢慢地...

actor的创建/停止是否存在内存泄漏?

Actor 创建和消息传递都是异步的,当 actorOf returns 时这并不意味着 actor 已经创建,而当 ! returns 时则不表示演员已经收到消息或根据消息采取行动。

这意味着你实际上不是在每次迭代中创建和停止一个actor,而是你触发创建并发送消息,这个循环在排队创建actor时可能比消息到达并触发停止填满 JVM 堆的消息。

要执行我认为您正在尝试执行的操作,您必须在收到 StopCmd 时提供演员的响应,并在继续下一次迭代之前在循环内等待该响应。这可以通过 ask 模式和 Await.result 一起完成,以阻塞主线程直到 actor 回复返回。

请注意,这仅对您的理解有用,而不是您在使用 Akka 的实际系统中会做的事情。