Назад | Перейти на главную страницу

java.lang.OutOfMemoryError: невозможно создать новый собственный поток

Я постоянно получаю это исключение при попытке запустить тесты Junit на моем Mac:

java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:658)
        at java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(ThreadPoolExecutor.java:727)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:657)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:92)
        at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:197)
        at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction.run(ApiProxyLocalImpl.java:184)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.google.appengine.tools.development.ApiProxyLocalImpl.doAsyncCall(ApiProxyLocalImpl.java:172)
        at com.google.appengine.tools.development.ApiProxyLocalImpl.makeAsyncCall(ApiProxyLocalImpl.java:138)

Один и тот же набор модульных тестов отлично проходит в Ubuntu и Windows.

Некоторая информация о моих системных ресурсах на Mac:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 266
virtual memory          (kbytes, -v) unlimited

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07-334-10M3326)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02-334, mixed mode)

Я не думаю, что это проблема приложения, потому что одни и те же тесты проходят в разных средах. Я попытался установить кучу на 1024 м, 512 м и установить стек на 64 КБ и 128 КБ (и каждую из этих комбинаций), но безуспешно. Изначально у меня было 256 открытых файлов, а я увеличил его до 1024.

Я немного погуглил, и все сообщения говорят, что нужно уменьшить размер кучи и увеличить размер стека, но это, похоже, не помогает. У кого-нибудь есть еще идеи?

РЕДАКТИРОВАТЬ: Вот некоторая информация о среде в моем ящике ubuntu:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)

Выделите jvm больше памяти. Обычно причина в этом. Если у вас 1 ГБ, добавьте 0,5 ГБ или 1. В зависимости от объема оперативной памяти вам необходимо оставить 1-2 ГБ ОЗУ для процессов ОС. Не выделяйте памяти больше, чем у вас есть.

Как сказал Мэт, это может быть проблема со слишком большим количеством открытых файлов, но в этом случае вы должны увидеть такое сообщение. Ищите это в логах.

Это могло быть max user processes ты бьешь. Попробуйте увеличить его до 1024.

ulimit -u 1024

На это есть глобальные ограничения, так что проверьте sysctl.conf и посмотрите на результат:

sysctl kern.maxprocperuid kern.maxproc

и при необходимости отрегулируйте.

размер стека (кбайт, -с) 8192

Это значение слишком велико для большого многопоточного приложения. Если вы запускаете много потоков, попробуйте установить его на 1024 с помощью ulimit -s или в /etc/security/limits.conf

Другой подход - настроить размер стека JVM, как указано здесь: Предотвращение "OutOfMemory: невозможно создать новую тему" используя Javas -Xss нестандартный вариант (см. также документация по инструментам)

Это может быть целесообразным вариантом, если вы не можете контролировать / уменьшать количество потоков (например, когда виновником является сторонняя библиотека или фреймворк, от которых вам не разрешено отказываться)