2010-08-17 2 views
6

я видел комментарии, как этотjava.lang.OutOfMemoryError: не удалось создать новую родную нить

one place i have seen this problem is if you keep creating threads, and instead of calling start(), call run() directly on the thread object. This will result in the thread object not getting dereferenced... So after sometime the message unable to create new native thread comes up

на Sun Java Forums

В моем приложении initialy мы планируем использовать нить, но позже, мы решили больше нет необходимости, поэтому мы просто вызываем run() вместо start(). Нужно ли делать ручную GC для нового threadClass (..)?

мой кот установка

-Xms1024m -Xmx1024m -XX:MaxPermSize=450m 
+3

Но если вы запускаете run() вместо start(), JVM не создаст новый поток. Не так ли? – sourcerebels

+0

согласился. так что, хотя я использую новый threadClass (..) для моего метода уровня обслуживания, не нужно делать ручную очистку? – cometta

+0

Зачем вам нужно создавать темы внутри Tomcat (веб-сервера)? Это не рекомендуется. Попробуйте найти альтернативное решение: 1) отдельный автономный процесс с потоками, обменивающимися через RMI, JMS или базу данных; 2) возможно, используя MessageDrivenBeans и JMS внутри вашего веб-приложения, если вы в порядке с переходом на сервер приложений J2EE, например JBoss, Glassfish или Geronimo; 3) other ... :) – helios

ответ

11

Почему вы создаете Thread?

Ваш код должен реализовывать интерфейс Runnable.

Затем, когда вы решите, что вы хотите, чтобы запустить его в потоке, просто экземпляр Thread с Runnable в качестве аргумента и вызвать start() на Thread объекта.

Если вместо этого вы просто хотите запустить его в своем текущем потоке, просто позвоните run() на свой Runnable объект.

Это имеет ряд преимуществ:

  • вы не связаны какие-либо Thread объектов до тех пор, пока вы не заботитесь об отдельных нитей
  • код обернут в Runnable, который подходит ближе концептуально: вы «Не пишете какой-то особый вид нитки, не так ли? Вы просто пишете код, который может быть запущен/запущен.
  • вы можете легко переключиться на использование в Executor который далее абстрагироваться от решения

И последнее, но не в последнюю очередь вы избежать возможной путаницы на том или не создан уроженцем ресурс резьбы.

+0

Вы имеете в виду мой threadClass extends Thread вызывают эту проблему?хотя я просто вызываю run(), а не запускаю? – cometta

+2

@cornetta - он не говорит, что это вызывает проблемы. Он говорит, что «плохая практика» расширяет «Thread». –

+0

Кроме того, в том же духе, почему бы не использовать Исполнителя? –

4

При вызове запуска() метод не новый поток не должен быть создан при запуске. И ваши объекты будут собираться сборщиком мусора, если на них не ссылаются.

Ваша другая часть кода может содержать много потоков.

Попробуйте использовать код ThreadPoolExecutor (объединение потоков) в свой код, чтобы ограничить потоки в приложении, и соответствующим образом настройте размер потока для лучшей производительности.

Вы также можете проверить следующие отлаживать вопрос: (ссылка из ссылки) Есть несколько вещей, чтобы делать, если вы столкнулись это исключение.

  • Используйте команду PID Lsof -p (Unix платформы), чтобы увидеть, сколько потоков активны в этом процессе.
  • Определите, существует ли максимальное число количество потоков на каждый процесс, определенный операционной системой. Если предел слишком низок для приложения, попробуйте , увеличив лимит потока для каждого процесса.
  • Проверьте код приложения, чтобы определить, есть ли код, который создание потоков или соединения (такой как соединения LDAP), а не уничтожающих их. Вы можете сбросить потоки Java , чтобы узнать, существует ли избыточное число .
  • Если вы обнаружили, что приложение открывает много соединений , сделайте уверенным, что всякий поток, созданный приложением , будет уничтожен. Приложение бизнес-приложения (.ear) или Web (.war) работает под долгой версией JVM . Просто потому, что приложение закончено, это не означает, что процесс JVM заканчивается. Это необходимо, чтобы приложение бесплатное любые ресурсы, которые он выделяет. Другое решение для приложения использовать пул потоков для для управления потоками.
1

Эта ссылка описывает довольно хорошо, как эта ошибка возникает в JVM: http://javaeesupportpatterns.blogspot.ro/2012/09/outofmemoryerror-unable-to-create-new.html

В основном это очень зависит от операционной системы. В RedHat Linux 6.5 (скорее всего, другие версии дистрибутива/версии и ядра) max_threads = max_process x 2.

Максимальное количество потоков зависит от количества разрешенных процессов. Какое максимальное количество процессов зависит от максимальной физической памяти, которую вы установили.

Если у вас есть файл limits.conf (на моем RHL 6.5 он находится в /etc/security/limits.d/90-nproc.conf). Выполните форму:

# Default limit for number of user's processes to prevent 
# accidental fork bombs. 
# See rhbz #432903 for reasoning. 

*   soft nproc  **1024** 
root  soft nproc  unlimited 

Вы увидите, что для пользователей без root это 1024 (что означает максимальные потоки 2048).

Чтобы просмотреть максимальное количество потоков, которые пользователь может создать, запустите эту команду «cat/proc/sys/kernel/threads-max» или «sysctl kernel.threads-max».

Чтобы решить проблему, как это (по крайней мере, он работал для меня) как корень вам нужно ncrease Максимальный допустимый резьб:

эхо 10000>/Труды/SYS/ядро ​​/ резьба-макс

Это затрагивает всех пользователей и корень. Пользователю необходимо выйти из системы, а затем снова войти в систему, чтобы настройки повлияли на них.

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

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