Memory AKKA Actor的内存泄漏

Memory AKKA Actor的内存泄漏,memory,out-of-memory,akka,actor,Memory,Out Of Memory,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

我有一个简单的测试程序来尝试

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
  }
}
object ActorLeak扩展应用程序{
val系统=ActorSystem(“ActorLeak”)
val次=100000000
为了(我)停止自我
}
}
我发现:有时OutOfMemoryError,有时使JVM死机,运行缓慢


参与者的创建/停止是否存在内存泄漏?

参与者创建和消息传递都是异步的,当
actorOf
返回时,这并不意味着参与者已经被创建,当
返回时,这并不意味着参与者已经收到或执行了消息

这意味着您实际上不是在为每个迭代创建和停止一个参与者,而是在触发创建并发送一条消息时,这个循环排队等待参与者创建的速度可能比消息到达并触发消息停止的速度要快,消息会填满JVM的堆

要执行您想执行的操作,我认为您必须在收到
StopCmd
时提供参与者的响应,并在循环中等待该响应,然后再继续下一次迭代。这可以通过
ask
模式和
wait.result
一起执行,以阻止主线程,直到执行该操作或已回复


请注意,这仅对您的理解有用,而不是在实际使用Akka的系统中执行的操作。

参与者创建和消息传递都是异步的,当
actorOf
返回时,这并不意味着参与者已经创建,当
返回时,并不意味着参与者已经接收或执行了您的操作留言

这意味着您实际上不是在为每个迭代创建和停止一个参与者,而是在触发创建并发送一条消息时,这个循环排队等待参与者创建的速度可能比消息到达并触发消息停止的速度要快,消息会填满JVM的堆

要执行您想执行的操作,我认为您必须在收到
StopCmd
时提供参与者的响应,并在循环中等待该响应,然后再继续下一次迭代。这可以通过
ask
模式和
wait.result
一起执行,以阻止主线程,直到执行该操作或已回复


请注意,这只对您的理解有用,而不是在实际使用Akka的系统中执行的操作。

我将for循环重写为递归函数,认为可能是
1到
范围的分配占用了内存;但我仍然看到随着时间的推移,内存使用量有了显著的线性增加时间(类似于您的结果)。我将for循环重写为一个递归函数,认为可能是
1到
范围的分配占用了内存;但我仍然看到随着时间的推移内存使用率显著、线性增加(类似于您的结果)。