scala,spray,akka - java.lang.OutOfMemoryError:无法创建新的本机线程

Rah*_*Dev 2 scala akka spray

在检查喷雾api的吞吐量时.

场景:25个并发用户

Os:免费BSD

内存:2GB

无核心:2

在大约13个并发用户中,我收到以下错误.

[ERROR] [06/29/2015 05:01:56.407] [default-akka.actor.default-dispatcher-2]     [ActorSystem(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-2] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled
java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:714)
    at scala.concurrent.forkjoin.ForkJoinPool.tryAddWorker(ForkJoinPool.java:1672)
    at scala.concurrent.forkjoin.ForkJoinPool.deregisterWorker(ForkJoinPool.java:1795)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:117)
Run Code Online (Sandbox Code Playgroud)

Akka和Spray Conf从默认值更改:

akka{
    tcp{
        register-timeout = 20s
    }
}

spray.can {
    request-timeout = 30 s
    bind-timeout = 30s
    unbind-timeout = 5s
    registration-timeout = 30s
}

http.spray.can {
    server{
        pipelining-limit = 50
    }
}
Run Code Online (Sandbox Code Playgroud)

导致OutOfMemmoryError的原因.从路由器actor抛出异常

dk1*_*k14 7

无法读懂心灵,但可能你会Await.result在演员内部阻挡(或类似).ForkJoinPool为每个被阻止的线程自动创建一个新线程.因此,如果你有一个长时间的块count_of_threads == count_of_requests(+每个线程持有引用iside调用堆栈),这最终会导致OutOfMemory.

看,阻止需要谨慎管理

PS 在这里你可能会发现为什么Await.result(scala.concurrent.blocking在内部使用)导致无法管理的线程创建ForkJoinPool(甚至不管maxParallelism).


或者你创建了很多ActorSystems,同一页的akka​​文档说明:

ActorSystem是一个重量级结构,它将分配1 ... N个线程,因此每个逻辑应用程序创建一个.