Подтвердить что ты не робот

Сколько ресурсов потребляют спальные и ожидающие потоки

Мне интересно, как дорого стоит много потоков в состоянии ожидания в java 1.6 x64.

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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