2014-04-14 1 views
2

나는 scala akka actorRef를 중심으로 꽤 기본적인 래퍼 클래스를 가지고있다. 기본적으로이 클래스는 actorRef 인 필드를 가지고 있으며 특정 메시지를 actorRef에 "알리는"메소드를 제공합니다. 이 방식으로 API를 지정하고 알림 또는 메시지 클래스 노출을 피할 수 있습니다. 내 프로그램에서 메모리 누수가 발생했습니다 및 akka 배우 주위에 래퍼 문제가 발생하는지 궁금하네요. 내 이론을 테스트하기 위해이 시뮬레이션을 아래에 작성했습니다.클래스의 akka 액터를 래핑하면 메모리 누수가 발생할 수 있습니까?

import akka.actor.{ActorSystem, ActorRef, PoisonPill} 
import akka.actor.ActorDSL._ 

implicit val as = ActorSystem() 

def createMemoryActor(): ActorRef = actor(new Act { 
    Array.fill(99999999)(1.0) // Just to take up memory 
    become { 
    case _ => print("testing memory leaks") 
    } 
}) 

val memoryActor = createMemoryActor() // memory usage jumps up 

memoryActor ! PoisonPill 
System.gc() // memory usage goes back down 

case class ActorWrapper() { 
    val memoryActor = createMemoryActor() 
} 

def doNothing(): Unit = { 
    val shouldGetGCed = ActorWrapper() 
() 
} 

doNothing() // memory usage jumps up 
System.gc() // memory usage goes back down 

위의 코드를 scala repl로 실행하고 jvisualvm을 실행하여 메모리 사용을 프로파일 링했습니다. "shouldGetGCed"참조가 차고를 수집하고 actorRef 필드 (메모리를 차지함)가 가비지 수집됩니다. 이게 항상 사실인가요, 아니면 제가 빠진 것이 있습니까? 또한 특정 API를 고수하기 위해 액터를 래핑하는 모범 사례가있는 사람은 누구입니까?

+0

기록을 위해, 알려주지 않는 메시지를받을 수 없도록하는 행위를 피할 수는 없습니다. Akka 배우는 이런 식으로 투사 될 수 없습니다. 당신이 필요로하는 것은 그들에게 보내는 경로 이름뿐입니다. 당신이 모르는 이름을 찾는 방법이 있습니다. –

+0

@RandallSchulz 나는 배우가 메시지를받지 못하게하는 것에 대해 이야기하지 않는다고 확신합니다. 난 그냥 미리 정의 된 메시지를 보내는 방법에 대해 얘기하고 있어요 –

+0

당신은 감싸 인 배우를 멈추지 않습니다. 이것은 선택 사항이 아닙니다. –

답변

6

시작되는 모든 액터는 결국 정지되어야하며, 그렇게 될 때까지는 메모리를 소비합니다. 예를 들어 예를 들어 shouldGetGCed.memoryActor ! PoisonPill. 액터는 자연적으로 분산 엔티티이고 JVM은 분산 GC를 지원하지 않으므로 액터에 대한 자동 가비지 콜렉션은 없습니다.