Зачем уменьшать размер стека потоков Java JVM? - PullRequest
12 голосов
/ 12 апреля 2010

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

Как уменьшение размера стека потоков поможет при условии максимальной ошибки памяти?

Ответы [ 4 ]

9 голосов
/ 12 апреля 2010

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

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

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

4 голосов
/ 12 апреля 2010

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

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

2 голосов
/ 12 апреля 2010

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


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

2 голосов
/ 12 апреля 2010

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

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


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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...