【问题标题】:scala, spray, akka - java.lang.OutOfMemoryError: unable to create new native threadscala,spray,akka - java.lang.OutOfMemoryError:无法创建新的本机线程
【发布时间】:2015-09-15 13:47:17
【问题描述】:

在检查spray api的吞吐量时。

场景:25 个并发用户

操作系统:免费 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)

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
    }
}

是什么导致了 OutOfMemoryError。 router actor

抛出异常

【问题讨论】:

    标签: scala akka spray


    【解决方案1】:

    不能读心,但可能你在演员内部做阻塞(Await.result 或类似的)。 ForkJoinPool 自动为每个被阻塞的线程创建一个新线程。所以如果你有一个长时间阻塞count_of_threads == count_of_requests(+每个线程都持有iside调用堆栈的引用),这最终会导致OutOfMemory

    见,Blocking Needs Careful Management

    附: Here 你可能会发现为什么 Await.result(它在内部使用 scala.concurrent.blocking)会导致在 ForkJoinPool 中无法管理地创建线程(即使不考虑 maxParallelism)。


    或者你创建了很多ActorSystems、same page of akka documentation 状态:

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

    【讨论】:

    • 我在演员内部制作 Await.result。现在我删除了它并使它成为未来。但是其他参与者有阻塞调用,例如 REST 调用。会不会是这个问题。
    • 应用程序中有 2 个参与者系统。现在做到了,似乎正在工作。你能解释一下行为的变化吗?
    • 正如我所说,我无法读心 :) - 更少的演员系统 - 更少的内存,所以它可能会有所帮助。但是两个actor系统不足以成为这个异常的直接原因(也许你有很多actor系统的“def”工厂——那么这可能是一个问题)。你确定 ActorSystem 删除有帮助还是它实际上正在删除 Await.result?回答你的第一个问题 - 阻塞 REST 调用可能不会导致这个异常(但它仍然很糟糕),因为它们的阻塞是无法管理的,ForkJoinPool 对此一无所知他们,所以它不会创建新线程。
    • 知道了。我在一个演员内部创建了一个演员系统,这样每次调用该演员时,它都会创建一个演员系统。 :) 感谢您的快速帮助。
    • Np。将此添加到答案中以使其正确。
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多