Вопрос

Я знаю, что локальные переменные и параметры методов живут в стеке, но я не могу понять, где на самом деле находятся методы в случае Java?

Если я объявлю какой-либо объект Thread, например:

Thread t=new Thread();
t.start();

Это значит, что я создал отдельный вызов методов помимо основного метода. Что это значит? Означает ли это вызов отдельной последовательности методов из памяти стека? Я прав?

Это было полезно?

Решение

Каждому потоку выделяется свой собственный стек.

В этой статье есть хорошее введение к разделению памяти в процессе Java.

  

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

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

Другие советы

Если я правильно помню, сам код метода будет жить в части кода, в то время как объявленные внутри него переменные будут жить в стеке, а объекты будут создаваться в куче. В Java указатели и примитивы переменных живут в стеке, а все созданные объекты - в куче.

Для (плохого) представления ASCII:

-------
|STACK|
-------
|FREE |
-------
|HEAP |
-------
|CODE |
-------

Где STACK представляет стек, FREE представляет свободную память, HEAP представляет кучу, а CODE представляет пространство кода.

Об этом говорит моя память - некоторые детали могут быть неправильными.

Стек состоит из вызовов методов. То, что java помещает в стек, - это запись вызова метода, которая инкапсулирует все переменные (как параметры, так и локально созданные экземпляры переменных) для этого метода. Когда вы запускаете приложение Java, единственный метод в стеке - главный метод (который автоматически включает параметр args):

main(args)

Когда говорят, что вы создаете объект Foo и вызываете foo.method (), стек теперь выглядит следующим образом:

method()
main(args)

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

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

Стек содержит все локальные переменные и все активные вызовы методов. В куче хранится все остальное.

Что касается вашего подвопроса: это означает, что новый стек создается с собственной выделенной памятью. В то время как ваш новый поток будет использовать общее пространство кучи (памяти), выделенное jvm

Куча разбита на несколько поколений.

Байт-код и соответствующий ему JIT-скомпилированный машинный код живут в так называемой постоянной генерации вместе с интернированными строками и другими данными классов.

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

Фактический байт-код и / или JIT-код будет находиться в памяти процесса. Вероятно, в памяти процесса будет только одна его копия, поскольку все потоки в данном процессе совместно используют эту память. Любые переменные shared этими потоками будут доступны общим методам. Локальные для потоков переменные (даже локальные переменные метода, используемые в потоке) будут создаваться в памяти этого потока.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top