I'm creating an actor per unit of work. Each actor creates a thread pool. when the work is completed it messages its sender which will inturn send the child actor a poison pill
I noticed that the number of threads in the jvm process is still growing indefinitly even though the child actors are "killed"
Example
class ParentActor (...) extends Actor {
....
....
val childActor = props(...child actor props...)
val resultFuture = childActor ? "do some work"
...
resultFuture onComplete {
...
childActor ! PoisonPill // "kill" the child actor
}
class ChildActor(...) extends Actor {
val executionContext: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
...
receive {
...
sender ! "done"
}
override def postStop() {
println("post stop called") // the actor prints this
}
}
Shouldn't the actor be GCd along with its threads?
Thread pools don't get automatically garbage collected. See the docs for the Java ThreadPoolExecutor
A pool that is no longer referenced in a program AND has no remaining threads may be reclaimed (garbage collected) without being explicitly shutdown.
But since you are creating a fixed pool, it will never have "no remaining threads". So it will never be collected by the JVM, even though the child actor is stopped.
You could implement a cleanup method in a postStop
, calling shutdownNow()
. But, as Thilo points out, managing thread pools in child actors is pretty weird. You don't explain why you want to do that, but I'd consider letting Akka manage your threads.