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 的实际系统中会做的事情。
我有一个简单的测试程序可以尝试...
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 的实际系统中会做的事情。