2008-09-19 3 views
19

Мне интересно, как дорого стоит много потоков в состоянии ожидания в java 1.6 x64.Сколько ресурсов спящих и ожидающих потоков потребляют

Чтобы быть более конкретным, я пишу приложение, которое работает на многих компьютерах и отправляет/принимает данные от одного к другому. Мне удобнее иметь отдельный поток для каждой подключенной машины и задачи, например: 1) отправка данных, 2) получение данных, 3) восстановление соединения при его удалении. Итак, учитывая, что в кластере есть N узлов, каждая машина будет иметь 3 потока для каждого из N-1 соседей. Как правило, будет 12 машин, которые достигают 33 коммуникационных потоков.

Большинство из этих потоков будут спать большую часть времени, поэтому для целей оптимизации я мог бы уменьшить количество потоков и дать больше работы каждому из них. Например, как. восстановление соединения связано с получением потока. Или отправка на все подключенные машины осуществляется одиночной нитью.

Так есть ли значительное влияние на много спальных нитей?

ответ

15

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

Я был в этой ситуации сам, и когда число соединений увеличилось более чем на 500 подключений (около тысячи потоков), вы, как правило, попадаете во множество случаев, когда вы получаете OutOfMemoryError, поскольку использование пространства стека потоков превышает максимальный объем памяти для одного процесса. По крайней мере, в нашем случае, который был в Java на 32-битном Windows-мире. Вы можете настроить мелочи и получить немного больше, я думаю, но, в конце концов, это просто не очень масштабируемо, так как вы тратите много памяти.

Если вам нужно большое количество подключений, Java NIO (новый IO или что-то еще) - это путь, позволяющий обрабатывать множество соединений в одном потоке.

Сказав это, вы не должны сталкиваться с большой проблемой, связанной с потоками 100 на достаточно современном сервере, даже если это, вероятно, все еще пустая трата ресурсов.

+0

Не следует использовать JRocikt JVM для решения этих проблем - поскольку я читал, он был разработан для обработки тысяч потоков. – 2008-09-19 10:37:28

+0

У меня нет опыта с JRockit JVM, поэтому я действительно не могу прокомментировать это. Сказав это, я знаю, что большинство операционных систем будут плохо работать с тысячами потоков, поэтому я не знаю, как JRockit справляется с этой проблемой ... – Liedman 2008-10-30 08:38:04

1

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

1

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

И если вам почему-то нужно сделать notifyAll() по какой-то причине, то, разумеется, вы пробуждаете множество дополнительных потоков, хотя вам может и не понадобиться делать это в предложенной вами архитектуре.

Я не уверен, что вы можете легко избежать одного потока для каждого сокета для прослушивания в этой модели (хотя я мало что знаю о NIO, который может исправить даже эту проблему), но посмотрите на интерфейс java.util.concurrent.Executor и его реализацию классы для достойного способа избежать слишком большого количества дополнительных потоков. В самом деле, ThreadPoolExecutor может быть хорошим способом управления вашими потоками прослушивания, поэтому вы не тратите слишком много времени на создание и уничтожение потоков.

2

У нас была такая же проблема, прежде чем мы перешли на NIO, поэтому я буду второй рекомендацией Liedmans пойти с этой картой.Вы должны уметь найти учебное пособие, но если вы хотите получить подробную информацию, я могу порекомендовать Java NIO Рон Хитченс.

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

0

Из тестов, которые я провел в C, Lua и Python, вы можете сделать свой собственный сон или функцию ожидания с очень маленькими строками кодов, чтобы сделать простой легкий цикл. Используйте локальную переменную с указанием времени в будущем, которое вы хотите достичь, а затем проверьте текущую временную метку в цикле while. Если вы находитесь в области, где вы работаете с fps, запустите функцию ожидания один раз за кадр, чтобы сохранить ресурсы. Чем больше точности вам нужно, рассмотрите использование часов вместо метки времени, так как временная метка ограничена секундами. Чем больше строк кода вы добавляете в функцию ожидания, тем менее точным оно становится и чем больше ресурсов он потребляет, хотя что-то менее 10 строк должно быть достаточно быстрым.

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