2015-06-29 2 views
2

При проверке пропускной способности распыления api.scala, spray, akka - java.lang.OutOfMemoryError: не удалось создать новую собственную нить

Сценарий: 25 одновременных пользователей

Os: Free 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 и спрей 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 
    } 
} 

Что вызывает OutOfMemmoryError. Исключение выбрасывается с роутер-актер

ответ

7

не может читать мысли, но, вероятно, вы блокируете (Await.result или аналогичные) внутри актеров. ForkJoinPool автоматически создает новый поток для каждого заблокированного. Так что если у вас есть длинные блоки count_of_threads == count_of_requests (+ каждый поток содержит ссылки, то есть стек вызовов), что в конечном итоге вызывает OutOfMemory.

See, Blocking Needs Careful Management

P.S. Here вы можете найти почему Await.result (который использует scala.concurrent.blocking внутри) приводит к неуправляемому созданию потоков в ForkJoinPool (даже вне зависимости от maxParallelism).


Или создать много ActorSystem с, same page of akka documentation состояний:

An ActorSystem is a heavyweight structure that will allocate 1…N Threads, so create one per logical application.

+0

Я делал Await.result внутри актеров. Теперь я удалил это и перешел в будущее. Но у других участников есть блокирующие вызовы, такие как звонки REST. Будет ли это проблемой. –

+0

Имело 2 действующие системы в приложении. Теперь он превратился в одного и, похоже, работает. Не могли бы вы объяснить изменения в поведении. –

+0

Как я уже сказал, я не могу читать мысли :) - меньше актерских систем - меньше памяти, поэтому это может немного помочь. Но двух актерских систем недостаточно, чтобы быть прямой причиной этого исключения (возможно, у вас была фабрика '' def' с множеством актерских систем, - тогда это может быть проблемой). Вы уверены, что удаление ActorSystem помогло или фактически удалило «Await.result»? Отвечая на ваш первый вопрос - блокировка вызовов REST, вероятно, не вызовет этого исключения (однако это все равно плохо), потому что их блокировка неуправляема и 'ForkJoinPool' знает ничего о них, чтобы он не создавал новый поток. – dk14

Смежные вопросы