Search code examples
memoryout-of-memoryakkaactor

Memory leak of AKKA Actor


I have a simple test program to try ...

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
  }
}

I found: sometime OutOfMemoryError, sometimes make JVM die, run slowly slowly ...

Is there memory leak in creation / stop of actors?


Solution

  • Actor creation and messaging are both asynchronous, when actorOf returns this does not mean the actor has been created yet, and when ! returns it does not mean the actor has received or acted upon the message.

    This means that you are actually not creating and stopping an actor for each iteration, but that you trigger creation, and send a message, this loop is probably quicker in queueing up actor creation than the messages can arrive and trigger the stopping of the messages which fills up the heap of your JVM.

    To do what you I think you are trying to do you would have to provide a response from the actor upon receiving the StopCmd and wait for that inside of your loop before continuing with the next iteration. This can be done with the ask pattern together with Await.result to block the main thread until the actor reply has returned.

    Note that this is only useful for your understanding and not something that you would do in an actual system using Akka.