我有一个简单的测试程序试试......
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死掉,慢慢地运行......
演员的创建/停止是否存在内存泄漏?
答案 0 :(得分:4)
演员创建和消息传递都是异步的,当actorOf
返回时,这并不意味着演员已经创建,并且当!
返回时并不意味着演员已接收或采取行动。
这意味着你实际上并没有为每次迭代创建和停止一个actor,而是你触发创建并发送一条消息,这个循环可能比消息到达时更快地排队actor创建并触发停止填充JVM堆的消息。
要做你认为你想要做的事情,你必须在收到StopCmd
时提供演员的回应并在继续下一次迭代之前等待循环内部。这可以使用ask
模式和Await.result
来完成,以阻止主线程,直到返回actor更新。
请注意,这仅对您的理解有用,而不是您在使用Akka的实际系统中可以执行的操作。