2013-11-17 5 views
51

Я понимаю, что каждый поток имеет свой собственный stack. Примитивные типы и ссылки хранятся в стеке и что в стек не помещается объект. Мои вопросы:Размер стека Java по умолчанию

  • Сколько может расти стек? (например, с параметрами - Xms и - Xmx)
  • Можем ли мы ограничить его рост?
  • Имеет ли стек минимальное значение по умолчанию и максимальное значение?
  • Как работает сборщик мусора в стеке?
+0

просто небольшое замечание для людей, читающих это: Escape-Analysis (Java 6 Update 21 и выше) позволяет хранить объекты в стеке. Меньше работы для сборщика мусора. – miraclefoxx

+0

Частичный дубликат http://stackoverflow.com/questions/6020619/where-to-find-default-xss-value-for-sun-oracle-jvm – Vadzim

ответ

57

Сколько может расти стек?

Чтобы настроить максимальный размер стека, вы можете использовать опцию VM с именем ss. Опция VM обычно передается с использованием -X {option}. Таким образом, вы можете использовать java -Xss1M для установки максимального размера стека на 1M.

Каждая нить имеет хотя бы один стек. Некоторые виртуальные машины Java (JVM) помещают Java-стек (вызовы методов Java) и собственный стек (вызовы Native-метода в виртуальной машине) в один стек и выполняют разматывание стека с помощью управляемого Managed to Native Frame, известной как M2NFrame. Некоторые JVM сохраняют два стека отдельно. Xss в большинстве случаев задает размер Java Stack.

Для многих JVM они устанавливают разные значения по умолчанию для размера стека на разных платформах.

Можем ли мы ограничить этот рост?

При вызове метода в стеке этого потока создается новый стек стека. Стек будет содержать локальные переменные, параметры, обратный адрес и т. Д. В java вы никогда не сможете поместить объект в стек, только ссылка на объект может быть сохранена в стеке. Поскольку массив также является объектом в java, массивы также не хранятся в стеке. Итак, если вы уменьшите количество локальных примитивных переменных, параметры, группируя их в объекты, вы можете уменьшить пространство на стеке. Фактически, тот факт, что мы не можем поместить объекты в стек java, влияет на производительность некоторое время (промахи в кеше).

Имеет ли стек какое-либо минимальное значение по умолчанию или максимальное значение по умолчанию?

Как я уже говорил, разные виртуальные машины отличаются друг от друга и могут изменять версии. См. here.

Как работает сбор мусора на стеке?

Сбор мусора на Java - это горячая тема. Сбор мусора направлен на сбор недостижимого объекта в куче. Так что нужно определение достижимого. Все в стеке является частью корневых ссылок в GC. Все, что доступно из каждой стопки каждой нити, должно рассматриваться как живое. Существуют также некоторые другие корневые ссылки, такие как объекты Thread и некоторые объекты класса.

Это только очень неопределенное использование стека на GC. В настоящее время большинство JVM используют GC поколения. This article дает краткое описание о Java GC. А недавно я прочитал a very good article, рассказывая о GC на .net. GC на oracle jvm довольно похож, поэтому я думаю, что это также может помочь вам.

+5

Хороший ответ. Я хотел бы добавить, что я считаю, что настройки по умолчанию консервативны, и они предназначены для охвата всех видов развертываний. Но, по моему опыту, даже с большими приложениями (более 500 тыс. Строк кода), работающими на серверах приложений, у меня никогда не было ошибки StackOverflow, даже если стек установлен на 256 тыс. (-Xss256k). Рассмотрим сервер приложений с 70 работающими потоками, со стеком 1 МБ по умолчанию, это дополнительный 70 МБ для процесса. – brettw

+4

'java -Xss 100M -jar testing.jar' забросил ошибку« Недопустимый размер стека потока: -Xss Ошибка: не удалось создать виртуальную машину Java ». но 'java -Xss100M -jar testing.jar' работал отлично. Запуск Windows 10 64-бит с Java «1.8.0_112». Должно ли ваше сообщение редактироваться, чтобы удалить пространство? –

+0

Для людей, использующих maven, это выглядит так: https://gist.github.com/belkacemlahouel/716f57e6e340ac581a7384e4607fd76e – belka

8

Как вы говорите, локальные переменные и ссылки хранятся в стеке. Когда метод возвращается, указатель стека просто перемещается обратно туда, где он был до запуска метода, то есть все локальные данные «удаляются из стека». Поэтому в стеке не требуется сборка мусора, что происходит только в куче.

Чтобы ответить на конкретные вопросы:

  • См this question о том, как увеличить размер стека.
  • Вы можете ограничить рост стека по:
    • группировка много локальных переменных в объекте: этот объект будет храниться в куче, и только ссылка хранится на стеке
    • предельного количества вложенной функции (обычно не используя рекурсию)
  • Для окон размер стека по умолчанию составляет 320 тыс. для 32-битных и 1024 тыс. для 64-битных, см. this link.
+0

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

+1

@asgs, в котором происходит сбор мусора. Если локальная переменная действительно была единственной ссылкой на объект, объект будет удален GC в какой-то момент после возвращения метода. Если метод добавил некоторую внешнюю ссылку на объект, GC не удалит его. –

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