2010-04-12 9 views
12

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

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

+1

потому что в стеке будет меньше данных? – Tedil

ответ

9

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

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

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

+0

ОК, я прослежу с VirtualVm и попытаюсь выяснить, нужно ли менять пространство стека или нет. я предполагаю, что это не будет. – djangofan

2

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

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


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

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

4

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

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

+1

Сжатые указатели объектов, введенные в Hotspot 6u14, помогают уменьшить это. Http: //wikis.sun.ком/дисплей/HotSpotInternals/CompressedOops –

2

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


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

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