Есть ли место в стеке для каждого потока?
Если я правильно понимаю, стек предназначен для локальных примитивов и ссылок на объекты в куче. Так что же происходит, если у вас более одного потока?
Разделяют ли они одно и то же пространство стека в одно и то же время (но разные области), или JRE переключает контексты и загружает-выгружает содержимое стека при переключении между потоками?
Или JRE выделяет отдельные стеки для каждого потока?
4 ответа
Или JRE выделяет отдельные стеки для каждого потока?
Концептуально да. (См. Эту ссылку спецификации JVM, например.)
То, как концептуализация спецификации реализуется в конкретной JVM, зависит от конкретной реализации. Однако я понимаю, что JVM текущего поколения (например, Hotspot) выделяют каждый стек в отдельном блоке памяти, запрашиваемом у ОС; например, используя mmap
системный вызов 1.
Конечно, при переключении потоков оптовое копирование содержимого стека отсутствует. Однако переключение контекста потока влечет за собой сохранение и загрузку регистров и (косвенно) дополнительную нагрузку на кэш-память и записи TLB. Это может быть важно... именно поэтому чрезмерное переключение контекста потока (например, вызванное конфликтом блокировок или чрезмерным ожиданием / уведомлением) может ухудшить производительность.
1 - Насколько я помню, некоторые JVM включают в себя доступную только для чтения страницу "красной зоны" в конце каждого сегмента стека. (Это означает, что переполнение стека потоков вызывает сбой памяти, и JVM не нужно явно проверять переполнение стека при каждом вызове метода, что может быть значительным ударом по производительности.) В любом случае, я понимаю, что "красная зона" msgstr "страница требует, чтобы стеки потоков запрашивались с помощью mmap.
Каждый поток имеет свой собственный стек, который содержит фрейм для каждого метода, выполняемого в этом потоке, как вы можете видеть здесь в разделе "На поток".
Или JRE выделяет отдельные стеки для каждого потока?
Да. JVM предназначена для этого:
Каждый поток виртуальной машины Java имеет собственный стек виртуальной машины Java, созданный одновременно с потоком. Стек виртуальной машины Java хранит кадры. [...] Поскольку стек виртуальной машины Java никогда не обрабатывается напрямую, за исключением кадров push и pop, кадры могут выделяться кучей.
Потоки Java представлены объектами потока, каждому потоку назначается отдельный стек потоков, используемый для хранения данных времени выполнения. Стек потока имеет определенный размер (может быть установлен с помощью опции VM java -Xss1m Application
).
Если во время выполнения Поток пытается сохранить больше даты, чем позволяет размер стека, возникает ошибка переполнения стека.