Почему уменьшают размер Java стопка потока JVM?

Я читал статью об обработке Из условий Ошибки памяти в Java (и на платформе JBoss), и я видел это предложение для сокращения размера threadstack.

Как был бы, уменьшая размер справки threadstack с макс. условием ошибки памяти?

12
задан Matt Fenwick 16 October 2012 в 17:20
поделиться

4 ответа

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

Обратной стороной этого является то, что вы увеличиваете вероятность ошибки переполнения стека.

Обратите внимание, что стеки потоков создаются вне кучи JVM, поэтому даже если в куче достаточно памяти, вы все равно можете не создать стек потоков из-за нехватки памяти (или исчерпания адресного пространства. , как правильно указывает Том Хотин).

9
ответ дан 2 December 2019 в 19:53
поделиться

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


Я так и не понял этого даже после тщательного изучения.Но опять же, я, возможно, никогда не сталкивался с комбинацией веб-приложение / контейнер, которую можно было бы настроить, изменив размер стека потоков. У меня были гораздо лучшие (и не смертельные) результаты по изменению коэффициента выживаемости. Но это был мой опыт работы . В разных рабочих местах и ​​приложениях YMMV.

2
ответ дан 2 December 2019 в 19:53
поделиться

В процессе N потоков, и для каждого стека потоков выделяется M байтов памяти. Общий объем памяти, выделенной для использования стека, равен N x M.

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


Часто поток не использует весь стек. Он предварительно выделен «на случай», что он понадобится позже, но если поток не использует глубокий путь вызова или не использует рекурсию, ему может не понадобиться все пространство стека, выделенное от его имени.

Поиск оптимального размера стека может быть искусством.

2
ответ дан 2 December 2019 в 19:53
поделиться

Проблема существует на 32-битных JVM, где адресное пространство может быть исчерпано. Уменьшение максимального размера стека обычно не уменьшает количество реально выделяемой памяти. Рассмотрим 8k потоков с 256kB, зарезервированных для стека 1k из 2MB, это 31 бит адресного пространства (2GB), ушедший туда.

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

4
ответ дан 2 December 2019 в 19:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: