2015-12-03 295 views
1

我有一個簡單的測試程序來嘗試...內存泄漏

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

我把你的for循環重寫爲一個遞歸函數,認爲它可能是咀嚼內存的'1 to times'範圍的分配;但是我仍然看到隨着時間的推移內存使用量的顯着增長(類似於您的結果)。 –

回答

4

演員創建和消息傳遞都是異步的,當actorOf返回時,這並不意味着演員已創建,並且當!返回時,並不表示演員已收到消息或對消息採取行動。

這意味着你實際上並不是爲每次迭代創建和停止一個actor,而是觸發創建併發送一條消息,這個循環在排隊創建actor時可能比消息到達並觸發stop的消息填滿了你的JVM堆。

要做你認爲你正在嘗試做的事情,你必須在接收到StopCmd後提供演員的迴應,然後等待循環內部再繼續下一次迭代。這可以通過ask模式連同Await.result來阻止主線程,直到參與者回覆已經返回。

請注意,這僅用於您的理解,而不是您在使用Akka的實際系統中所做的操作。